使用geopandas+Python3.9.5调用gdf.size()报numpy.int32不可调用
报错成因
- Geopandas的GeoDataFrame继承自Pandas的DataFrame,其中
size是属性而非可调用方法,它直接返回GeoDataFrame中包含的总元素个数(值为 行数 × 列数),属于numpy.int32类型的数值。你在后面加了括号()相当于尝试调用一个数值对象,自然会抛出TypeError: 'numpy.int32' object is not callable的错误。 - 额外注意:就算你去掉括号用
gdf.size也不符合你的需求,你要遍历行需要获取的是行数,而size返回的是总元素数,你应该用len(gdf)或者gdf.shape[0]来获取行数。
原有实现的额外问题
你写的循环删行逻辑存在严重缺陷:每次删除行之后,GeoDataFrame的长度会动态变小,而你循环的range是根据初始长度生成的,会出现索引错位、漏判、甚至索引越界报错的问题,完全不推荐用循环遍历的方式删行。
正确解决方案
1. 修正size调用的写法
如果需要获取总元素数,直接写不带括号的:
print(gdf.size)
如果需要获取行数,用以下两种写法均可:
# 写法1 print(len(gdf)) # 写法2 print(gdf.shape[0])
2. 更高效的删行实现(无需循环)
你要删除所有adm0_a3等于AUS的行,直接用Pandas/Geopandas原生的布尔索引过滤即可,一行代码就能完成,性能远高于自行实现循环:
gdf = gdf[gdf['adm0_a3'] != 'AUS']
如果你需要保留过滤过程的打印日志,可以用迭代行的方式iterrows(),但注意不要在迭代原对象的同时删原对象,可以先收集要删除的索引再统一删除:
drop_indexs = [] for idx, row in gdf.iterrows(): print("test", idx) if row['adm0_a3'] == 'AUS': drop_indexs.append(idx) gdf = gdf.drop(drop_indexs)
内容的提问来源于stack exchange,提问作者Zach W.
相关产品推荐
相关产品推荐

