将 lambda 函数应用于地理数据框的行时出错
Mistake with lambda function applied on geodataframe's row
我正在尝试将点的 3D 地理数据框转换为 2D。所以我开发了以下功能:
def point3D_to_2D(point3D_wkt: shapely.geometry.point.Point) -> shapely.geometry.point.Point:
print(point3D_wkt)
point2D_wkt = transform(lambda x, y, z=None: (x, y), point3D_wkt).wkt
print(point2D_wkt)
return point2D_wkt
我的地理数据框的名称是 geom
(我有很多幻想!),几何列的名称是 geometry
。使用以下代码:
geom['geometry'] = geom.apply(lambda row : point3D_to_2D(row.geometry))
我看到这个错误:
AttributeError: 'Series' object has no attribute 'geometry'
但使用 type(geom)
我看到:
geopandas.geodataframe.GeoDataFrame
将 3D 几何图形转换为 2D
- 这是一个简单的例子,不使用点的最后一个(第 3 个)z 坐标
- 无需使用 WKT 字符串
- 你的代码有一个问题是你正在使用
apply()
到 GeoDataFrame,而且没有注意 axis=1
它将逐行
- 仅使用 GeoSeries 就简单得多,因此无需考虑数据框轴
gdf["geometry"].apply(lambda p: shapely.geometry.Point(p.coords[0][:-1]))
数据源3D点
head(10)
输出显示它是 3D 几何体(POINT Z)
import geopandas as gpd
import pandas as pd
import shapely
df = pd.read_html("https://en.wikipedia.org/wiki/List_of_cities_by_elevation")[1]
df["Lat"] = pd.to_numeric(df["Latitude"].replace({"N":"+","S":"-"}, regex=True), errors="coerce")
df["Lon"] = pd.to_numeric(df["Longitude"].replace({"E":"+","W":"-"}, regex=True), errors="coerce")
df["Elevation (m)"] = pd.to_numeric(df["Elevation (m)"], errors="coerce")
df = df.dropna(subset=["Lat","Lon","Elevation (m)"])
gdf = gpd.GeoDataFrame(df, geometry=gpd.points_from_xy(df["Lon"], df["Lat"], df["Elevation (m)"]), crs="epsg:4386")
gdf.head(10)
Country/Territory
City Name/s
Continental Region
Latitude
Longitude
Population
Elevation (m)
Lat
Lon
geometry
0
Nepal
Pokhara
Asia
N28.2096
E83.9856
523000
822
28.2096
83.9856
POINT Z (83.9856 28.2096 822)
1
South Africa
Bloemfontein
Africa
S29.116667
E026.216667
747431
1395
-29.1167
26.2167
POINT Z (26.216667 -29.116667 1395)
2
China
Shanghai
Asia
N31.2304
E121.4737
2.632e+07
122
31.2304
121.474
POINT Z (121.4737 31.2304 122)
3
Nepal
Butwal
Asia
N27.6866
E83.4323
120982
150
27.6866
83.4323
POINT Z (83.4323 27.6866 150)
4
Italy
Milan
Europe
N45.4625
E9.186389
1.37869e+06
122
45.4625
9.18639
POINT Z (9.186389 45.4625 122)
5
Kazakhstan
Pavlodar
Asia
N52.3000
E76.950000
353930
123
52.3
76.95
POINT Z (76.95 52.3 123)
6
South Africa
Pretoria
Africa
S25.746111
E028.188056
2.92149e+06
1339
-25.7461
28.1881
POINT Z (28.188056 -25.746111 1339)
7
Albania
Tirana
Europe
N41.3317
E019.8172
557422
110
41.3317
19.8172
POINT Z (19.8172 41.3317 110)
8
Austria
Vienna
Europe
N48.2092
E016.3728
1.89906e+06
170
48.2092
16.3728
POINT Z (16.3728 48.2092 170)
9
Belarus
Minsk
Europe
N53.9678
E027.5766
1.98244e+06
198
53.9678
27.5766
POINT Z (27.5766 53.9678 198)
我正在尝试将点的 3D 地理数据框转换为 2D。所以我开发了以下功能:
def point3D_to_2D(point3D_wkt: shapely.geometry.point.Point) -> shapely.geometry.point.Point:
print(point3D_wkt)
point2D_wkt = transform(lambda x, y, z=None: (x, y), point3D_wkt).wkt
print(point2D_wkt)
return point2D_wkt
我的地理数据框的名称是 geom
(我有很多幻想!),几何列的名称是 geometry
。使用以下代码:
geom['geometry'] = geom.apply(lambda row : point3D_to_2D(row.geometry))
我看到这个错误:
AttributeError: 'Series' object has no attribute 'geometry'
但使用 type(geom)
我看到:
geopandas.geodataframe.GeoDataFrame
将 3D 几何图形转换为 2D
- 这是一个简单的例子,不使用点的最后一个(第 3 个)z 坐标
- 无需使用 WKT 字符串
- 你的代码有一个问题是你正在使用
apply()
到 GeoDataFrame,而且没有注意axis=1
它将逐行 - 仅使用 GeoSeries 就简单得多,因此无需考虑数据框轴
gdf["geometry"].apply(lambda p: shapely.geometry.Point(p.coords[0][:-1]))
数据源3D点
head(10)
输出显示它是 3D 几何体(POINT Z)
import geopandas as gpd
import pandas as pd
import shapely
df = pd.read_html("https://en.wikipedia.org/wiki/List_of_cities_by_elevation")[1]
df["Lat"] = pd.to_numeric(df["Latitude"].replace({"N":"+","S":"-"}, regex=True), errors="coerce")
df["Lon"] = pd.to_numeric(df["Longitude"].replace({"E":"+","W":"-"}, regex=True), errors="coerce")
df["Elevation (m)"] = pd.to_numeric(df["Elevation (m)"], errors="coerce")
df = df.dropna(subset=["Lat","Lon","Elevation (m)"])
gdf = gpd.GeoDataFrame(df, geometry=gpd.points_from_xy(df["Lon"], df["Lat"], df["Elevation (m)"]), crs="epsg:4386")
gdf.head(10)
Country/Territory | City Name/s | Continental Region | Latitude | Longitude | Population | Elevation (m) | Lat | Lon | geometry | |
---|---|---|---|---|---|---|---|---|---|---|
0 | Nepal | Pokhara | Asia | N28.2096 | E83.9856 | 523000 | 822 | 28.2096 | 83.9856 | POINT Z (83.9856 28.2096 822) |
1 | South Africa | Bloemfontein | Africa | S29.116667 | E026.216667 | 747431 | 1395 | -29.1167 | 26.2167 | POINT Z (26.216667 -29.116667 1395) |
2 | China | Shanghai | Asia | N31.2304 | E121.4737 | 2.632e+07 | 122 | 31.2304 | 121.474 | POINT Z (121.4737 31.2304 122) |
3 | Nepal | Butwal | Asia | N27.6866 | E83.4323 | 120982 | 150 | 27.6866 | 83.4323 | POINT Z (83.4323 27.6866 150) |
4 | Italy | Milan | Europe | N45.4625 | E9.186389 | 1.37869e+06 | 122 | 45.4625 | 9.18639 | POINT Z (9.186389 45.4625 122) |
5 | Kazakhstan | Pavlodar | Asia | N52.3000 | E76.950000 | 353930 | 123 | 52.3 | 76.95 | POINT Z (76.95 52.3 123) |
6 | South Africa | Pretoria | Africa | S25.746111 | E028.188056 | 2.92149e+06 | 1339 | -25.7461 | 28.1881 | POINT Z (28.188056 -25.746111 1339) |
7 | Albania | Tirana | Europe | N41.3317 | E019.8172 | 557422 | 110 | 41.3317 | 19.8172 | POINT Z (19.8172 41.3317 110) |
8 | Austria | Vienna | Europe | N48.2092 | E016.3728 | 1.89906e+06 | 170 | 48.2092 | 16.3728 | POINT Z (16.3728 48.2092 170) |
9 | Belarus | Minsk | Europe | N53.9678 | E027.5766 | 1.98244e+06 | 198 | 53.9678 | 27.5766 | POINT Z (27.5766 53.9678 198) |