首页 > 解决方案 > 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)

标签: pythonpandasperformancedictionarygeopy

解决方案


迭代数据帧 withiterrows是一种方便的方法,但性能很差。

在这里,您应该:

  1. 从原始 DataFrame 中提取唯一地址
  2. 计算这些唯一地址的地理坐标(暂时忘记这里的熊猫)
  3. 用于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)

推荐阅读