Estoy buscando algunas sugerencias sobre cómo hacer que mi código de Python sea más eficiente. Normalmente, la eficiencia no me importa, pero ahora estoy trabajando con un archivo de texto de ubicaciones de EE. UU. Con más de 1,5 millones de puntos. Con la configuración dada, se tarda unos 5 segundos en ejecutar operaciones en un punto; Necesito bajar esta cifra.
Estoy usando tres paquetes diferentes de Python GIS para hacer algunas operaciones diferentes en los puntos y generar un nuevo archivo de texto delimitado.
- Utilizo OGR para leer un archivo de forma de límite de condado y obtener acceso a la geometría de límite.
- Comprobaciones bien proporcionadas para ver si un punto está dentro de alguno de estos condados.
- Si está dentro de uno, uso la biblioteca de archivos de forma de Python para extraer información de atributos del límite .dbf.
- Luego escribo información de ambas fuentes en un archivo de texto.
Sospecho que la ineficiencia radica en tener un ciclo de 2-3 niveles ... no estoy muy seguro de qué hacer al respecto. Particularmente busco ayuda con alguien con experiencia en el uso de cualquiera de estos 3 paquetes, ya que es la primera vez que uso alguno de ellos.
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"