es.davy.ai

Preguntas y respuestas de programación confiables

¿Tienes una pregunta?

Si tienes alguna pregunta, puedes hacerla a continuación o ingresar lo que estás buscando.

Correspondencia eficiente de vecino más cercano para dos GeoDataFrames.

Estoy haciendo procesamiento a distancia en dos dataframes (100k líneas y 1M líneas).
En este momento, mi procesamiento demora 20 días y me gustaría ver si puedo mejorar mi código para acelerar el proceso.
Usé geopandas después de una sugerencia aquí, lo que aceleró considerablemente la clasificación en mi iteración, pero me pregunto si podría codificarlo de manera diferente o utilizar algunas mejores prácticas.

Aquí están mis tablas:

dfb:

osm_id name type … surf centro valeurseuil
0 579194418 yes … 31.698915 [450755.82645944477, 1751747.6864094366] 9.529465
1 579207356 yes … 13.176170 [451636.3912408436, 1749870.2332154014] 6.143854
2 579211060 ruins … 38.139254 [452363.0241478424, 1748257.9797045246] 10.452795
3 369649074 yes … 48.625159 [451683.6453331233, 1748501.9621812948] 11.802577
4 267028254 REFUGE DU MAUPAS yes … 56.936793 [453183.133164252, 1747379.3537066604] 12.771527
… … … … … … … …
935472 252424617 NaN yes … 20.135543 [562867.4086043949, 1835680.070006147] 7.595004
935473 252424662 NaN yes … 26.000756 [562843.7024093983, 1835627.7568757713] 8.630567
935474 252424658 NaN yes … 26.933184 [562823.0171366152, 1835635.2213349422] 8.783956
935475 252424810 NaN yes … 40.663507 [562827.2984292071, 1835603.3674661077] 10.793163
935476 252424878 NaN yes … 49.335093 [562822.9908286823, 1835585.4379250652] 11.888424

[935477 filas x 9 columnas]

gdfo:

ogc_fid id code_cs … coordpoints surf centro
0 3 OCSGE0000000000000741775 CS2.2.1 … [[495777.7174760493, 1805519.5430061778], [495… 1174.564617 [495632.1007243945, 1805463.0834386032]
1 16 OCSGE0000000000000947172 CS2.2.1 … [[544263.7691919031, 1824731.9681054198], [544… 20054.686775 [544368.7095351141, 1824617.8708354477]
2 25 OCSGE0000000000000949293 CS2.2.1 … [[535161.228444845, 1844915.1013712562], [5351… 295.911740 [535212.0861638768, 1844894.4575003278]
3 29 OCSGE0000000000000947839 CS2.2.1 … [[533186.6035670156, 1837867.7088815654], [533… 3466.870293 [533173.6347083747, 1837936.4649687177]
4 193406 OCSGE0000000000000739484 CS2.2.1 … [[458053.7764636817, 1757545.0501438894], [458… 4424.495046 [457942.74975193664, 1757488.5605310446]
… … … … … … … …
83870 393015 OCSGE0000000000000807891 CS2.2.1 … [[513245.68605544185, 1819995.2010655974], [51… 3416.327411 [513269.2562117624, 1819960.69636371]
83871 393050 OCSGE0000000000000176585 CS2.2.1 … [[483728.63284117245, 1781422.0428754487], [48… 0.032123 [483713.9059494421, 1781392.2606697257]
83872 393057 OCSGE0000000000000813649 CS2.2.1 … [[516662.97000782896, 1860487.2357337545], [51… 722.841230 [516719.98876274703, 1860521.6746725072]
83873 393062 OCSGE0000000000000954112 CS2.2.1 … [[543018.616240293, 1832845.9711751717], [5430… 481.191268 [543013.2243556273, 1832823.7731046807]
83874 393071 OCSGE0000000000001016440 CS2.2.1 … [[530307.8027104639, 1843478.1113854842], [530… 88.841634 [530310.0204813549, 1843428.549428356]

[83875 filas x 9 columnas]
Aquí está mi código:

dfb = pd.read_csv(building, sep=’#’)
dfo = pd.read_csv(occsol, sep=’#’)
dfb[‘geot’] = ‘non’
gs = gpd.GeoSeries.from_wkt(dfo[‘geometry’], crs=’EPSG:27572′)
gdfo = gpd.GeoDataFrame(dfo, geometry=gs)
dfb[‘valeurseuil’] = 3 * ((dfb[‘surf’] / 3.141592653589793) ** (1 / 2)) # esto es un umbral
m = 0
fin = len(dfb)
for i in range(len(dfb)):
gdfo[‘dist’] = gdfo[‘geometry’].distance(Point(dfb.iloc[i][‘centro’][0], dfb.iloc[i][‘centro’][1]))
gdfo = gdfo.sort_values(by=’dist’)
for j in range(2): # 3 primeros polígonos ordenados por distancia ascendente
XYPtj = gdfo.iloc[j][‘coordpoints’]
compteur = 0
temp = []
for l in XYPtj:
dist = self.distancepoint([dfb.iloc[i][‘centro’], l])
temp.append(dist)
for d in temp:
if d < dfb.iloc[i][‘valeurseuil’]: # umbral
compteur += 1 #

Tags:  , , ,

Answer

  1. Avatar for davy.ai

    Sugerencias para mejorar el código

    1. En lugar de utilizar un bucle for anidado, podemos intentar usar la vectorización mediante funciones de NumPy. Esto puede acelerar significativamente el tiempo de procesamiento.

    2. También podemos intentar paralelizar el código utilizando multiprocessing o Dask. Al usar múltiples núcleos, podemos procesar los dataframes en paralelo, reduciendo el tiempo total de procesamiento.

    3. También podemos intentar optimizar la función de cálculo de distancia. En lugar de utilizar la distancia euclidiana, podría ser más eficiente utilizar funciones de cálculo de distancia geodésica proporcionadas por GeoPandas u otras bibliotecas.

    4. Podemos considerar el uso de un índice espacial para acelerar la búsqueda del vecino más cercano. Se pueden utilizar R-tree o KD-tree con este fin.

    Comentarios adicionales

    1. Es importante perfilar el código para identificar los cuellos de botella y las áreas donde se puede optimizar el código.

    2. Dependiendo de la naturaleza de los datos, podría ser beneficioso preprocesar los datos reduciendo el número de filas, eliminando duplicados o filtrando datos irrelevantes.

    3. Es esencial elegir las estructuras de datos y algoritmos adecuados para mejorar el rendimiento del código.

    4. Por último, siempre es una buena práctica mantener el código modular y bien documentado para facilitar el mantenimiento y las futuras mejoras.

Comments are closed.