python - Python 遍历 Pandas DataFrame 并添加使用 geopy.geocoders Nominatim 性能建议计算的新值
问题描述
我有一个包含几百万行的 .csv 文件。行包含有关位置(街道名称)的数据,我正在尝试将该街道名称转换为经度和纬度,因为我正在尝试进行一些地理分析。这样做的问题是处理单行大约需要 0.5 秒。
我尝试使用动态编程改进我的代码并将已经计算的值保存在字典中,以便我可以重用它们,但这只会将计算单行所需的时间缩短到大约 0.3 秒。
街道名称确实重复了很多,当我在大约第 1000 行时,我从字典中获得了大约 50% 的命中,不幸的是,这似乎仍然太慢了。如果有人知道如何改进此代码,我会全神贯注,因为当前代码或多或少没用,因为迭代所有行需要一周时间。
我当前的代码如下所示:
def long_lat_to_csv(dataset, output_file):
dataset['longitude'] = None
dataset['latitude'] = None
geolocator = Nominatim(user_agent="test")
longlat = dict()
area = "New York City, USA"
for i, row in dataset.iterrows():
if int(i) % 100 == 0:
print('current row:', i)
address = row['Street Name']
try:
# if address already calculated:
long, lat = longlat[address]
dataset.at[i, 'longitude'] = long
dataset.at[i, 'latitude'] = lat
except:
# if address isn't calculated yet
try:
loc = geolocator.geocode(address + ',' + area)
longlat[address] = [loc.longitude, loc.latitude]
except:
# also store addresses that return None
longlat[address] = None
dataset.to_csv(output_file, index=False)
解决方案
迭代数据帧 withiterrows
是一种方便的方法,但性能很差。
在这里,您应该:
- 从原始 DataFrame 中提取唯一地址
- 计算这些唯一地址的地理坐标(暂时忘记这里的熊猫)
- 用于
merge
将这些坐标复制回原始 DataFrame
它可能变成:
geolocator = Nominatim(user_agent="test")
area = "New York City, USA"
addresses = dataset['Street Name'].drop_duplicates()
addresses = pd.concat(addresses,
pd.DataFrame([loc.longitude, loc.latitude] for address in addresses
for loc in [geolocator.geocode(address + ',' + area)]],
index=addresses.index, columns=['longitude', 'latitude']))
dataset = dataset.merge(addresses, on=['Street Name'])
dataset.to_csv(output_file, index=False)
推荐阅读
- javascript - 我怎样才能从不同的标签中获取然后发送 id?
- discord.py - 如何在我的代码中指定不和谐的文本通道?
- javascript - 当小数因精度而被截断时,如何使用 parseFloat 向下舍入?
- node.js - discord.js 尝试赋予角色时无法读取未定义的属性添加
- javascript - 阻止一个元素通过浏览器缩放按比例缩放?
- typescript - TypeScript 令人困惑的错误'对象可能是'未定义'和'类型上不存在属性'长度''
- mysql - 我们可以防止从数据库表中读取排他锁定的行吗?
- javascript - 如何将音频工作集连接到网页?
- mysql - Laravel Eloquent 支持 MariaDb 动态专栏
- docker - 通过另一个不相关的容器连接到 Mariadb 容器