【问题标题】:Is it bad practice to have more than 1 geometry column in a GeoDataFrame?在 GeoDataFrame 中有超过 1 个几何列是不好的做法吗?
【发布时间】:2020-02-05 04:00:31
【问题描述】:

我正在尝试创建一个 GeoDataFrame,每行有 2 个邮政编码,我想比较它们之间的距离。 我列出了大约 220 个邮政编码并在它们上运行 itertools 组合以获取所有组合,然后将元组解压缩为两列

code_combo = list(itertools.combinations(df_with_all_zip_codes['code'], 2))
df_distance_ctr = pd.DataFrame(code_combo, columns=['first_code','second_code'])

然后我进行了一些标准的 pandas 合并和列重命名,以将多边形/几何列从原始地理数据框放入这个新的列中,就在相应的邮政编码列旁边。 问题是我似乎无法将多边形列读取为几何,即使在 1.) 尝试将数据帧转换为地理数据帧 - AttributeError: No geometry data set yet, 2. ) 将 wkt.loads 应用于几何列 - AttributeError: 'MultiPolygon' object has no attribute 'encode' . 我试图寻找一种将系列转换为地理系列的方法,但在 SO 和文档上都找不到任何东西。谁能指出我可能出错的地方?

【问题讨论】:

  • 请分享您的部分数据以帮助人们理解您的问题。
  • 来自文档(入门,概念,第 2 段):“您可以拥有任意多的几何列,桌面 GIS 软件没有典型的限制。”

标签: gis polygon series geopandas shapely


【解决方案1】:

查看https://github.com/geopandas/geopandas/blob/master/geopandas/geodataframe.py 的 GeoDataFrame 的 __init__ 方法,看起来 GDF 一次只能有一列。不过,您创建的其他列中仍应包含几何对象。

由于每列中仍有几何对象,您可以编写一个使用 Shapely 的 distance 方法的方法,如下所示:

import pandas as pd
import geopandas
from shapely.geometry import Point
import matplotlib.pyplot as plt

lats = [-34.58, -15.78, -33.45, 4.60, 10.48]
lons = [-58.66, -47.91, -70.66, -74.08, -66.86]
df = pd.DataFrame(
    {'City': ['Buenos Aires', 'Brasilia', 'Santiago', 'Bogota', 'Caracas'],
     'Country': ['Argentina', 'Brazil', 'Chile', 'Colombia', 'Venezuela'],
     'Latitude': lats,
     'Longitude': lons})

df['Coordinates'] = list(zip(df.Longitude, df.Latitude))
df['Coordinates'] = df['Coordinates'].apply(Point)

df['Coordinates_2'] = list(zip(lons[::-1], lats[::-1]))
df['Coordinates_2'] = df['Coordinates_2'].apply(Point)

gdf = geopandas.GeoDataFrame(df, geometry='Coordinates')


def get_distance(row):
    distance = row.Coordinates.distance(row.Coordinates_2)
    print(distance)
    return distance

gdf['distance'] = gdf.apply(lambda row: get_distance(row), axis=1)

至于AttributeError: 'MultiPolygon' object has no attribute 'encode'MultiPolygon 是一个 Shapely 几何类。 encode 通常是字符串对象的方法,因此您可以删除对 wkt.loads 的调用。

【讨论】:

  • 感谢 wkt.loads 的简洁说明!此外,在从多边形创建两个质心列(其中第一个是指定的几何列)之后,该功能就像一个魅力。 df_distance_ctr = gpd.GeoDataFrame(df_distance_ctr, geometry='first_mpoly') df_distance_ctr['first_centroid'] = df_distance_ctr['first_mpoly'].centroid df_distance_ctr['second_centroid'] = df_distance_ctr.apply(lambda row: row.second_mpoly.centroid, axis=1) 根据 geometry not set 错误,这可能是我的操作顺序。或 .copy() 错误,因为重新运行代码工作正常。
猜你喜欢
  • 1970-01-01
  • 2021-08-29
  • 2020-08-19
  • 1970-01-01
  • 1970-01-01
  • 2011-02-14
  • 1970-01-01
  • 2020-09-07
  • 1970-01-01
相关资源
最近更新 更多