1 votos

Cómo extraer valores de un geodataframe para llenar columnas/filas correspondientes en otro geodataframe

Tengo 2 geodataframes; uno hecho de polígonos (bldg_res_df) y otro de puntos de centroide (parcel_res_df). Usé .concat para combinarlos en un único geodataframe y hacer algunos cálculos.

df_list = [bldg_res_df, parcel_res_df]
combined_df = gpd.GeoDataFrame(pd.concat(df_list, sort=True))

Resumí ciertas columnas basadas en una columna compartida (GEOID) entre ambos gdf's.

geoid_sum = combined_df[[ 'GEOID', 'bldg_sqft', 'CensusPop']]
geoid_sum = geoid_sum.groupby('GEOID').agg({'GEOID': 'count', 'bldg_sqft': 'sum', 'CensusPop': 'mean'}).reindex(combined_df['GEOID'])

Luego hice mis cálculos y llené previamente columnas vacías (Pop_By_Area, Tot_Bldg_Sqft, y Census_Bld_Units) con los resultados.

combined_df['Pop_By_Area'] = (geoid_sum['CensusPop'].values * 
combined_df['bldg_sqft'])/geoid_sum['bldg_sqft'].values
combined_df['Tot_Bldg_Sqft'] = geoid_sum['bldg_sqft'].values
combined_df['Census_Bld_Units'] = geoid_sum['GEOID'].values

Ahora lo que quiero hacer es llenar los geodataframes individuales con los valores recién calculados para la fila correspondiente. O, dividir el combine_df en 2 geodataframes basados en el tipo de geometría (polígonos, puntos). ¿Cuál es la manera más fácil de lograr esto?

2voto

SJT Puntos 1

Puedes dividir este dataframe usando cualquiera de los métodos que describiste.

Para mantener tus dataframes originales, puedes copiar los valores calculados ejecutando un apply fila por fila y buscando el dataframe combinado para el mismo GEOID.

EDITAR: Este método se ralentiza significativamente a medida que crece el número de elementos en los dataframes, ya que tiene que recorrer cada uno y buscar en combined_df. Esto puede mitigarse configurando 'GEOID' como el índice, ya que esto permitirá una búsqueda de hash (como en un diccionario o set)

# Establece GEOID como el índice de combined_df. drop=False, le indica a la función que mantenga GEOID en las columnas del dataframe.
combined_df.set_index('GEOID', drop=False, inplace=True)

bldg_res_df['Pop_By_Area'] = bldg_res_df['GEOID'].apply(lambda bldg_geoid: combined_df.loc[bldg_geoid, 'Pop_By_Area'])
parcel_res_df['Pop_By_Area'] = parcel_res_df['GEOID'].apply(lambda parcel_geoid: combined_df.loc[parcel_geoid, 'Pop_By_Area'])

Aunque una forma más rápida y simple sería dividir las columnas calculadas de tu dataframe combinado, y filtrar los tipos de geometría en nuevos dataframes. Geopandas almacena los tipos de geometría como objetos Shapely, por lo que puedes hacer uso del atributo .geom_type de la columna de geometría de combined_df en una llamada .loc.

points_df = combined_df.loc[combined_df['geometry'].geom_type == 'Polygon', ['GEOID', 'HU_Pop', 'PARCEL_ID', 'Pop_By_Area', 'STORY_NBR', 'Tot_Bldg_Sqft', 'bldg_sqft', 'geometry']]
polygon_df = combined_df.loc[combined_df['geometry'].geom_type == 'Point', ['GEOID', 'HU_Pop', 'PARCEL_ID', 'Pop_By_Area', 'STORY_NBR', 'Tot_Bldg_Sqft', 'bldg_sqft', 'geometry']]

1voto

King Puntos 118

Puedes usar merge para poblar tus geodataframes originales, lo cual asumo será significativamente más rápido que hacer un bucle como propuso @Nate.

bldg_res_df = bldg_res_df.merge(combined_df[['GEOID', 'Pop_By_Area', 'Tot_Bldg_Sqft', 'Census_Bld_Units']], on='GEOID', how='left')
parcel_res_df = parcel_res_df.merge(combined_df[['GEOID', 'Pop_By_Area', 'Tot_Bldg_Sqft', 'Census_Bld_Units']], on='GEOID', how='left')

i-Ciencias.com

I-Ciencias es una comunidad de estudiantes y amantes de la ciencia en la que puedes resolver tus problemas y dudas.
Puedes consultar las preguntas de otros usuarios, hacer tus propias preguntas o resolver las de los demás.

Powered by:

X