我正在尝试使用地理编码程序包将33000个zipcodes转换为坐标。我希望有一种方法来并行化这种方法,因为它消耗了相当多的资源。
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
答案 0 :(得分:2)
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没有正确解析最后一列的名称,并且包含大量尾随空格。您必须在使用前删除列名称。
答案 1 :(得分:-1)
使用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
延迟来缓解这种情况。