Tôi đang tìm kiếm một số gợi ý về cách làm cho mã python của tôi hiệu quả hơn. Thông thường hiệu quả không quan trọng đối với tôi nhưng tôi hiện đang làm việc với một tệp văn bản của các địa điểm ở Hoa Kỳ với hơn 1,5 triệu điểm. Với thiết lập đã cho, sẽ mất khoảng 5 giây để chạy các hoạt động trên một điểm; Tôi cần phải giảm con số này xuống.
Tôi đang sử dụng ba gói GIS python khác nhau để thực hiện một vài thao tác khác nhau trên các điểm và xuất ra tệp văn bản được phân tách mới.
- Tôi sử dụng OGR để đọc một shapefile ranh giới quận và có quyền truy cập vào hình dạng ranh giới.
- Hình dạng kiểm tra để xem nếu một điểm nằm trong bất kỳ quận nào.
- Nếu nó nằm trong một, tôi sử dụng Thư viện Shapefile của Python để lấy thông tin thuộc tính từ ranh giới .dbf.
- Sau đó tôi viết một số thông tin từ cả hai nguồn vào một tệp văn bản.
Tôi nghi ngờ rằng sự kém hiệu quả nằm ở việc có một vòng lặp 2-3 tầng ... không hoàn toàn chắc chắn phải làm gì về nó. Tôi đặc biệt tìm kiếm sự giúp đỡ với người có kinh nghiệm sử dụng bất kỳ gói nào trong số 3 gói này, vì đây là lần đầu tiên tôi sử dụng bất kỳ gói nào trong số đó.
import os, csv
from shapely.geometry import Point
from shapely.geometry import Polygon
from shapely.wkb import loads
from osgeo import ogr
import shapefile
pointFile = "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"
historicBounds = "US_Counties_1860s_NAD"
writeFile = "C:\\NSF_Stuff\\NLTK_Scripts\\Gazetteer_New\\NewNational_Gazet.txt"
#opens the point file, reads it as a delimited file, skips the first line
openPoints = open(pointFile, "r")
reader = csv.reader(openPoints, delimiter="|")
reader.next()
#opens the write file
openWriteFile = open(writeFile, "w")
#uses Python Shapefile Library to read attributes from .dbf
sf = shapefile.Reader("C:\\NSF_Stuff\\NLTK_Scripts\\Gazetteer_New\\US_Counties_1860s_NAD.dbf")
records = sf.records()
print "Starting loop..."
#This will loop through the points in pointFile
for row in reader:
print row
shpIndex = 0
pointX = row[10]
pointY = row[9]
thePoint = Point(float(pointX), float(pointY))
#This section uses OGR to read the geometry of the shapefile
openShape = ogr.Open((str(historicBounds) + ".shp"))
layers = openShape.GetLayerByName(historicBounds)
#This section loops through the geometries, determines if the point is in a polygon
for element in layers:
geom = loads(element.GetGeometryRef().ExportToWkb())
if geom.geom_type == "Polygon":
if thePoint.within(geom) == True:
print "!!!!!!!!!!!!! Found a Point Within Historic !!!!!!!!!!!!"
print str(row[1]) + ", " + str(row[2]) + ", " + str(row[5]) + " County, " + str(row[3])
print records[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(records[shpIndex][3]) + "|" + str(records[shpIndex][9]) + "|\n"))
if geom.geom_type == "MultiPolygon":
for pol in geom:
if thePoint.within(pol) == True:
print "!!!!!!!!!!!!!!!!! Found a Point Within MultiPolygon !!!!!!!!!!!!!!"
print str(row[1]) + ", " + str(row[2]) + ", " + str(row[5]) + " County, " + str(row[3])
print records[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(records[shpIndex][3]) + "|" + str(records[shpIndex][9]) + "|\n"))
shpIndex = shpIndex + 1
print "finished checking point"
openShape = None
layers = None
pointFile.close()
writeFile.close()
print "Done"