أكثر

استخدام OGR و Shapely بكفاءة أكبر؟

استخدام OGR و Shapely بكفاءة أكبر؟


أنا أبحث عن بعض الاقتراحات حول كيفية جعل كود Python الخاص بي أكثر كفاءة. عادةً لا تهمني الكفاءة ولكني أعمل الآن مع ملف نصي لمواقع الولايات المتحدة بأكثر من 1.5 مليون نقطة. مع الإعداد المحدد ، يستغرق الأمر حوالي 5 ثوانٍ لتشغيل العمليات على نقطة واحدة ؛ أنا بحاجة إلى خفض هذا الرقم.

أنا أستخدم ثلاث حزم مختلفة من نظام Python GIS للقيام ببعض العمليات المختلفة على النقاط وإخراج ملف نصي جديد محدد.

  1. أستخدم OGR لقراءة ملف أشكال حدود المقاطعة والوصول إلى هندسة الحدود.
  2. يتحقق بشكل رشيق لمعرفة ما إذا كانت هناك نقطة داخل أي من هذه المقاطعات.
  3. إذا كانت ضمن واحدة ، فأنا أستخدم مكتبة ملفات الأشكال Python لسحب معلومات السمات من الحدود .dbf.
  4. ثم أكتب بعض المعلومات من كلا المصدرين إلى ملف نصي.

أظن أن عدم الكفاءة يكمن في وجود حلقة من 2-3 طبقات ... لست متأكدًا تمامًا مما يجب فعله حيال ذلك. أنا أبحث بشكل خاص عن مساعدة مع شخص لديه خبرة في استخدام أي من هذه الحزم الثلاثة ، حيث إنها المرة الأولى التي استخدم فيها أيًا منها.

استيراد نظام التشغيل ، csv من shapely.geometry import Point من shapely.geometry ، استيراد المضلع من أحمال استيراد shapely.wkb من استيراد osgeo أو استيراد ملف شكل نقطة ملف = "C:  NSF_Stuff  NLTK_Scripts  Gazetteer_New  NationalFile_20110404.txt" shapeFolder = "C:  NSF_Stuff  NLTK_Scripts  Gazetteer_New" #historicBounds = "C:  NSF_Stuff  NLTK_Scripts  Gazetteer_New  US_Counties_1860s_NAD" historyBounds = "US_Counties_1860s_NAD" writeFile = "C:  NFT_Stuff  NewNational_Gazet.txt "# يفتح ملف النقطة ، ويقرأه كملف محدد ، ويتخطى السطر الأول openPoints = open (pointFile،" r ") reader = csv.reader (openPoints، delimiter =" | ") reader.next () # يفتح ملف الكتابة openWriteFile = open (writeFile، "w") #uses Python Shapefile Library لقراءة السمات من .dbf sf = shapefile.Reader ("C:  NSF_Stuff  NLTK_Scripts  Gazetteer_New  US_Counties_1860s_NAD.dbf" ) سجلات = sf.records () طباعة "حلقة البداية ..." # هذا سوف يمر عبر النقاط في pointFile للصف في القارئ: print row shpIndex = 0 pointX = row [10] pointY = row [9] thePoint = Point (float (pointX)، float (pointY)) # يستخدم هذا القسم OGR لقراءة هندسة ملف الشكل openShape = ogr.Open (( str (historyBounds) + ".shp")) طبقات = openShape.GetLayerByName (historyBounds) # يتم حلقات هذا القسم عبر الأشكال الهندسية ، ويحدد ما إذا كانت النقطة في مضلع لعنصر في الطبقات: geom = loads (element.GetGeometryRef (). ExportToWkb ()) إذا geom.geom_type == "المضلع": if thePoint.within (geom) == True: print !!!!!!!!!!!!! تم العثور على نقطة داخل التاريخية !!!!!!!!!!!! "print str (row [1]) +"، "+ str (row [2]) +"، "+ str (row [5]) + "County" + str (row [3]) طباعة السجلات [shpIndex] openWriteFile.write ((str (row [0]) + "|" + str (row [1]) + "|" + str (row [2]) + "|" + str (row [5]) + "|" + str (row [3]) + "|" + str (row [9]) + "|" + str (row [10 ]) + "|" + str (السجلات [shpIndex] [3]) + "|" + str (السجلات [shpIndex] [9]) + "|  n")) إذا geom.geom_type == "MultiPolygon": لـ pol في geom: if thePoint.within (pol) == True: print !!!!!!!!!!!!!!!!!! تم العثور على نقطة داخل المضلع المتعدد !!!!!!!!!!!!!! "print str (الصف [1]) +"، "+ str (row [2]) +"، "+ str (row [5 ]) + "مقاطعة" + str (صف [3]) طباعة السجلات [shpIndex] openWriteFile.write ((str (row [0]) + "|" + str (row [1]) + "|" + str (row [2]) + "|" + str (row [5]) + "|" + str (row [3]) + "|" + str (row [9]) + "|" + str (row [10]) + "|" + str (السجلات [shpIndex] [3]) + "|" + str (السجلات [shpIndex] [9]) + "|  n")) shpIndex = shpIndex + 1 print "منتهية نقطة التحقق "openShape = بلا طبقات = لا شيء pointFile.close () writeFile.close () طباعة" تم "

ستكون الخطوة الأولى هي تحريك ملف الشكل مفتوحًا خارج حلقة الصفوف ، فأنت تفتح وتغلق ملف الشكل 1.5 مليون مرة.

لأكون صادقًا على الرغم من أنني سأقوم بحشو كل شيء في PostGIS والقيام بذلك باستخدام SQL في الجداول المفهرسة.


نظرة سريعة على الكود الخاص بك يجلب بعض التحسينات إلى الذهن:

  • تحقق من كل نقطة مقابل المربع المحيط / مظروف المضلعات أولاً ، لإزالة القيم المتطرفة الواضحة. يمكنك أن تخطو خطوة إلى الأمام وتحسب عدد bboxes التي تكمن فيها النقطة ، إذا كانت واحدة بالضبط ، فلن تحتاج إلى اختبارها مقابل الهندسة الأكثر تعقيدًا (حسنًا ، ستكون في الواقع إذا كانت تكمن في المزيد من واحدة ، سوف تحتاج إلى مزيد من الاختبار. يمكنك إجراء تمريرين لإزالة الحالات البسيطة من الحالات المعقدة).

  • بدلاً من المرور عبر كل نقطة واختبارها مقابل المضلعات ، قم بالتكرار خلال المضلعات واختبر كل نقطة. تحميل / تحويل الهندسة بطيء ، لذا فأنت تريد القيام بذلك بأقل قدر ممكن. أيضًا ، قم بإنشاء قائمة بالنقاط من ملف CSV في البداية ، مرة أخرى لتجنب الاضطرار إلى القيام بذلك عدة مرات لكل نقطة ثم تجاهل النتائج في نهاية ذلك التكرار.

  • قم بفهرسة نقاطك مكانيًا ، والتي تتضمن تحويلها إما إلى ملف أشكال أو ملف SpatialLite أو شيء مثل قاعدة بيانات PostGIS / PostgreSQL. هذا له ميزة أن أدوات مثل OGR ستكون قادرة على القيام بمعظم العمل نيابة عنك.

  • لا تكتب المخرجات حتى النهاية: تعد print () وظيفة باهظة الثمن في أفضل الأوقات. بدلاً من ذلك ، قم بتخزين البيانات كقائمة ، واكتبها في النهاية باستخدام وظائف التخليل القياسية في Python أو وظائف إغراق القائمة.