我怎样才能使这个功能更有效/ 运行 它并行?

How can I make this function more efficient/ run it parallel?

我正在尝试使用地理编码器包将 33000 个邮政编码转换为坐标。我希望有一种方法可以并行化此方法,因为它会消耗相当多的资源。

from geopy.geocoders import ArcGIS
import pandas as pd
import time
geolocator = ArcGIS()
df1 = pd.DataFrame(0.0, index=list(range(0,len(df))), columns=list(['lat','lon']))
df = pd.concat([df,df1], axis=1)
for index in range(0,len(df)):
      row = df['zipcode'].loc[index]
      print index
#      time.sleep(1) 
#    I put this function in just in case it would give me a timeout error. 
      myzip = geolocator.geocode(row)
      try: 
        df['lat'].loc[index] = myzip.latitude
        df['lon'].loc[index] = myzip.longitude
      except: 
        continue 

geopy.geocoders.ArcGIS.geocode 查询网络服务器。单独发送 33,000 个查询可能会使您的 IP 被封禁,因此我不建议并行发送它们。

您正在查找美国的几乎每一个邮政编码。美国人口普查局有一个 1MB 的 CSV 文件,其中包含 33,144 个邮政编码的信息:https://www.census.gov/geo/maps-data/data/gazetteer2017.html.

您可以在几分之一秒内完成所有操作:

zip_df = pd.read_csv('2017_Gaz_zcta_national.zip', sep='\t')
zip_df.rename(columns=str.strip, inplace=True)

需要注意的一件事是最后一列的名称未被 Pandas 正确解析并且包含大量尾随空格。使用前必须去掉列名。

这是一种方法,使用 multiprocessing.Pool

from multiprocessing import Pool

def get_longlat(x):
    index, row = x
    print index
    time.sleep(1)
    myzip = geolocator.geocode(row['zipcode'])
    try:
        return myzip.latitude, myzip.longitude
    except:
        return None, None

p = Pool()
df[['lat', 'long']] = p.map(get_longlat, df.iterrows())

更一般地说,使用 DataFrame.iterrows(迭代的每个项目都是一个索引,行元组)可能比您在上面使用的基于索引的方法稍微更有效

编辑:阅读其他答案后,您应该了解速率限制;但是,您可以在 Pool 中使用固定数量的进程以及 time.sleep 延迟来在某种程度上缓解这种情况。