如何解决Geopy、pandas、FOR 循环失败
我正在自学geopy
。看起来简单明了,但我的代码不起作用。应该是:
- 将地址字段列表从 CSV 读入
pandas
df - 将地址字段连接成一个格式为
geopy
的列 - 从新列中创建一个列表
- 通过 for 循环将列表中的每一项送入
geopy
并返回坐标添加 坐标到原始 df 并将其导出为 CSV
#setup
from geopy.geocoders import Nominatim
import pandas as pd
#create the df
df = pd.DataFrame(pd.read_csv('properties to geocode.csv'))
df['Location'] = df['Street Address'].astype(str)+","+df['City'].astype(str)+","+df['State'].astype(str)
#create the geolocator object
geolocator = Nominatim(timeout=1,user_agent = "My_Agent")
#create the locations list
locations = df['Location']
#empty lists for later columns
lats = []
longs = []
#process the location list
for item in locations:
location = geolocator.geocode('item')
lat = location.latitude
long = location.longitude
lats.append(lat)
longs.append(long)
#add the lists to the df
df.insert(5,'Latitude',lats)
df.insert(6,'Longitude',longs)
#export
df.to_csv('geocoded-properties2.csv',index=False)
有些东西不起作用,因为它为每一行返回相同的纬度和经度值,而不是为每一行返回唯一的坐标。
我在其他地方找到了使用 .apply 的工作代码,但我有兴趣了解我做错了什么。有什么想法吗?
解决方法
- 您的代码不包含示例数据。使用了一些来自公共 API 的示例数据来演示
- 您的代码将一个文字传递给
geolocator.geocode()
- 它必须是与行关联的地址 - 提供了与 pandas
apply
一起使用的示例、列表推导式 和与 推导式 等效的for
循环强> - 结果表明所有三种方法都是等效的
from geopy.geocoders import Nominatim
import requests
import pandas as pd
searchendpoint = "https://directory.spineservices.nhs.uk/ORD/2-0-0/organisations"
# get all healthcare facilities in Herefordshire
dfhc = pd.concat([pd.json_normalize(requests
.get(searchendpoint,params={"PostCode":f"HR{i}","Status":"Active"})
.json()["Organisations"])
for i in range(1,10)]).reset_index(drop=True)
def gps(url,geolocator=None):
# get the address and construct a space delimted string
a = " ".join(str(x) for x in requests.get(url).json()["Organisation"]["GeoLoc"]["Location"].values())
lonlat = geolocator.geocode(a)
if not lonlat is None:
return lonlat[1]
else:
return (0,0)
# work with just GPs
dfgp = dfhc.loc[dfhc.PrimaryRoleId.isin(["RO180","RO96"])].head(5).copy()
geolocator = Nominatim(timeout=1,user_agent = "My_Agent")
# pandas apply
dfgp["lonlat_apply"] = dfgp["OrgLink"].apply(gps,geolocator=geolocator)
# list comprehension
lonlat = [gps(url,geolocator=geolocator) for url in dfgp["OrgLink"].values]
dfgp["lonlat_listcomp"] = lonlat
# old school loop
lonlat = []
for item in dfgp["OrgLink"].values:
lonlat.append(gps(item,geolocator=geolocator))
dfgp["lonlat_oldschool"] = lonlat
姓名 | OrgId | 状态 | OrgRecordClass | 邮政编码 | LastChangeDate | PrimaryRoleId | PrimaryRoleDescription | OrgLink | lonlat_apply | lonlat_listcomp | lonlat_oldschool | |
---|---|---|---|---|---|---|---|---|---|---|---|---|
7 | 艾尔斯通山手术 | M81026002 | 活动 | RC2 | HR1 1HR | 2020-03-19 | RO96 | 分支手术 | https://directory.spineservices.nhs.uk/ORD/2-0-0/organisations/M81026002 | (52.0612429,-2.7026047) | (52.0612429,-2.7026047) | |
9 | 巴尔斯法院学校 | 5CN91 | 活动 | RC2 | HR1 1EQ | 2021-01-28 | RO180 | 初级保健信托网站 | https://directory.spineservices.nhs.uk/ORD/2-0-0/organisations/5CN91 | (52.0619209,-2.7086105) | (52.0619209,-2.7086105) | |
13 | 博登汉姆外科 | 5CN24 | 活动 | RC2 | HR1 3JU | 2013-05-08 | RO180 | 初级保健信托网站 | https://directory.spineservices.nhs.uk/ORD/2-0-0/organisations/5CN24 | (52.152405,-2.6671942) | (52.152405,-2.6671942) | |
22 | 贝尔蒙特修道院 | 5CN16 | 活动 | RC2 | HR2 9RP | 2013-05-08 | RO180 | 初级保健信托网站 | https://directory.spineservices.nhs.uk/ORD/2-0-0/organisations/5CN16 | (52.0423056,-2.7648698) | (52.0423056,-2.7648698) | |
24 | 贝尔蒙特健康中心 | 5CN22 | 活动 | RC2 | HR2 7XT | 2013-05-08 | RO180 | 初级保健信托网站 | https://directory.spineservices.nhs.uk/ORD/2-0-0/organisations/5CN22 | (52.0407746,-2.739788) | (52.0407746,-2.739788) |
版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。