32 votos

Devolución de la latitud y la longitud del punto del centroide con GeoPandas

Me gustaría devolver el lat, lon o x, y del objeto de punto en la siguiente serie, ya que planeo vincularlos con una API que construí que vincula OSM y NetworkX. Los centroides se añadirán como nuevos nodos para el análisis de la red.

gp.GeoSeries(zones.centroid).x y gp.GeoSeries(zones.centroid).y como se indica en docs genera el siguiente error:

AttributeError: El objeto 'GeoSeries' no tiene el atributo 'x'

Modificando un poco las cosas e imprimiendo list(gp.GeoSeries(zones.centroid)) devuelve miles de puntos de forma con el siguiente formato:

[... <shapely.geometry.point.Point object at 0x0000000024035940>,
<shapely.geometry.point.Point object at 0x0000000024035978>, 
<shapely.geometry.point.Point object at 0x00000000240359B0>, 
<shapely.geometry.point.Point object at 0x00000000240359E8>, 
<shapely.geometry.point.Point object at 0x0000000024035A20>, 
<shapely.geometry.point.Point object at 0x0000000024035A58>, 
<shapely.geometry.point.Point object at 0x0000000024035A90>, 
<shapely.geometry.point.Point object at 0x0000000024035AC8>]

El código que estoy utilizando es el siguiente:

import geopandas as gp

zones = gp.GeoDataFrame.from_file(shp_file)

for index, row in zones.iterrows():
    print index, gp.GeoSeries(zones.centroid)

# result:
# 9700022.00    POINT (-122.8196050489696 54.00617624128658)
# 9700023.00    POINT (-122.7474362519174 53.99998921974029)
# 9700100.00    POINT (-121.4904983300892 53.98447191612864)
# 9700101.00    POINT (-122.5513619751679 53.73999791511078)
# 9700102.00    POINT (-123.0624037191615 53.62317549646422)
# 9700103.00    POINT (-123.0848175548173 54.05921695782788)

¿Cómo puedo devolver el x, y de las GeoPandas POINT ¿Objeto?

33voto

Mark H Puntos 2378

Yo mismo me encontré con este problema. Si quieres el x y y como columnas separadas de GeoDataFrame, entonces esto funciona bien:

gdf["x"] = gdf.centroid.map(lambda p: p.x)
gdf["y"] = gdf.centroid.map(lambda p: p.y)

A partir de la versión 0.3.0 de GeoPandas, se puede utilizar el x y y propiedades en su lugar:

gdf["x"] = gdf.centroid.x
gdf["y"] = gdf.centroid.y

19voto

Sork Puntos 26

Dejando el resto abajo, pero lo principal era acceder a la geometría correctamente. Si se itera sobre las filas, por ejemplo for index, row in zones.iterrows(): puede utilizar simplemente row.geometry.centroid.x y row.geometry.centroid.y . La geometría es una columna especial incluida en un GeoDataFrame, por lo que cada fila tiene un atributo de geometría.
Está accediendo a ese atributo, que contiene un shapely objeto. Que shapely tendrá un atributo, centroid que, a su vez, contiene un shapely.geometry.Point que tiene atributos x y y , dándole por fin las propiedades que desea.


(Esta parte fue el esfuerzo original para llegar a x,y con map y shapely.geometry.Point .)
Voy a suponer que quieres una lista de tuplas (x, y). Cree una función de acceso rápido para los atributos x e y en un Point y utilizar map .

Edición: Vale, he descubierto que puede estar accediendo a la geometría en el GeoDataFrame de forma incorrecta. La geometría es una columna en su GeoDataFrame, que por sí misma produce una serie. Llamando a centroid en esa columna debería darle una nueva GeoSerie de sólo esos centroides. Sospecho que la forma en que estabas haciendo las cosas era tomando el centroide de cada vértice en cada polígono. Todavía no puedo probar esto ya que no puedo instalar GeoPandas ahora mismo.

def getXY(pt):
    return (pt.x, pt.y)
centroidseries = zones['geometry'].centroid
centroidlist = map(getXY, centroidseries)

o si quieres dos listas separadas de coordenadas x e y

def getXY(pt):
    return (pt.x, pt.y)
centroidseries = zones['geometry'].centroid
x,y = [list(t) for t in zip(*map(getXY, centroidseries))]

Alternativamente, también debería poder utilizar zones.geometry.centroid en lugar de zones['geometry'].centroid . De cualquier manera, creo que llamar zones.centroid puede estar devolviendo un GeoDataFrame en lugar de una GeoSerie, dando la salida inesperada cuando se envuelve en otra GeoSerie.

6voto

John B Puntos 21

Esto se ha facilitado a partir de GeoPandas 0.3.0.

Ahora puede acceder a x y y de shapely Points dentro de un geopandas GeoSeries utilizando your_GeoDataFrame.geometry.x y your_GeoDataFrame.geometry.y

(Nota : Estoy usando python 3.6.1, no estoy seguro del comportamiento en 2.7, lo siento)

Fuente en github

5voto

user161642 Puntos 1272

La solución para extraer el punto central (latitud y longitud) del polígono y del multipolígono.

import geopandas as gpd
df = gpd.read_file(path + 'df.geojson')
#Find the center point
df['Center_point'] = df['geometry'].centroid
#Extract lat and lon from the centerpoint
df["lat"] = df.Center_point.map(lambda p: p.x)
df["long"] = df.Center_point.map(lambda p: p.y)

1voto

Diegov Puntos 21

Si sólo quieres un array numpy de centroides:

centroids = np.vstack([df.centroid.x, df.centroid.y]).T

o como un marco de datos con columnas adicionales (por ejemplo, el nombre):

pd.DataFrame(np.vstack([df.name, df.centroid.x, df.centroid.y]).T, columns=['name', 'x', 'y'])

ex.

   name                                           geometry
0     1  POLYGON ((0.00000 1.00000, 0.00000 0.00000, 1....
1     2  POLYGON ((2.00000 1.00000, 2.00000 0.00000, 3....

# ==>
# np.vstack([df.centroid.x, df.centroid.y]).T
#    array([[0.5, 0.5],
#           [2.5, 0.5]])

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