Python 在数据帧上迭代地理定位

Python 在数据帧上迭代地理定位,python,pandas,loops,geopy,Python,Pandas,Loops,Geopy,我有一个数据框,它有两列,医院名称和地址,我想遍历每个地址以找到纬度和经度。我的代码似乎占据了数据帧的第一行,我似乎无法选择地址来查找坐标 import pandas from geopy.geocoders import Nominatim geolocator = Nominatim() for index, item in df.iterrows(): location = geolocator.geocode(item) df["Latitude"].append(lo

我有一个数据框,它有两列,医院名称和地址,我想遍历每个地址以找到纬度和经度。我的代码似乎占据了数据帧的第一行,我似乎无法选择地址来查找坐标

import pandas
from geopy.geocoders import Nominatim

geolocator = Nominatim()
for index, item in df.iterrows():
    location = geolocator.geocode(item)
    df["Latitude"].append(location.latitude)
    df["Longitude"].append(location.longitude)
这是我用来抓取网站的代码。复制并运行此文件,您将拥有数据集

import requests
from bs4 import BeautifulSoup
import pandas
import numpy as np

r=requests.get("https://www.privatehealth.co.uk/hospitals-and-
clinics/orthopaedic-surgery/?offset=300")
c=r.content
soup=BeautifulSoup(c,"html.parser")
all=soup.find_all(["div"],{"class":"col-9"})
names = []
for item in all:
    d={}
    d["Hospital Name"] = item.find(["h3"],{"class":"mb6"}).text.replace("\n","")
    d["Address"] = item.find(["p"],{"class":"mb6"}).text.replace("\n","")
    names.append(d)
df=pandas.DataFrame(names)
df = df[['Hospital Name','Address']]
df
目前,数据如下所示(一个医院示例):

我试图实现的最终输出如下所示

Hospital Name   |Address         | Latitude | Longitude
Fulwood Hospital|Preston, PR2 9SZ|53.7589938|-2.7051618

这里似乎有一些问题。使用您提供的URL中的数据:

df.head()
                                Hospital Name                   Address
0                        Fortius Clinic City           London, EC4N 7BE
1  Pinehill Hospital - Ramsay Health Care UK           Hitchin, SG4 9QZ
2                  Spire Montefiore Hospital              Hove, BN3 1RD
3             Chelsea & Westminster Hospital           London, SW10 9NH
4   Nuffield Health Tunbridge Wells Hospital   Tunbridge Wells, TN2 4UL
(1)如果您的数据框列名确实是
医院名称
地址
,那么您需要在调用
geocode()
时使用
item.Address

只需使用
即可为您提供
医院名称
地址

for index, item in df.iterrows():
    print(f"index: {index}")
    print(f"item: {item}")
    print(f"item.Address only: {item.Address}")

# Output:
index: 0

item: Hospital Name    Fortius Clinic City 
Address              London, EC4N 7BE
Name: 0, dtype: object

item.Address only: London, EC4N 7BE
...
(2)您注意到数据框只有两列。如果这是真的,那么当您尝试对
df[“纬度”]
df[“经度”]
执行操作时,您将得到一个
keyrerror
,因为它们不存在

(3)
地址
列上使用
apply()
可能比
iterrows()更清晰
请注意,这是一个风格上的问题,值得商榷。(前两点是实际误差。)

例如,使用提供的URL:

from geopy.geocoders import Nominatim
geolocator = Nominatim()

tmp = df.head().copy()

latlon = tmp.Address.apply(lambda addr: geolocator.geocode(addr))

tmp["Latitude"] = [x.latitude for x in latlon]
tmp["Longitude"] = [x.longitude for x in latlon]
输出:

                                Hospital Name                   Address  \
0                        Fortius Clinic City           London, EC4N 7BE   
1  Pinehill Hospital - Ramsay Health Care UK           Hitchin, SG4 9QZ   
2                  Spire Montefiore Hospital              Hove, BN3 1RD   
3             Chelsea & Westminster Hospital           London, SW10 9NH   
4   Nuffield Health Tunbridge Wells Hospital   Tunbridge Wells, TN2 4UL   

    Latitude  Longitude  
0  51.507322  -0.127647  
1  51.946413  -0.279165  
2  50.840871  -0.180561  
3  51.507322  -0.127647  
4  51.131528   0.278068  

请提供一些样本数据以及您当前和预期的输出。这在一定程度上是有效的,只要地理编码器没有超时,每秒执行的请求不超过1个。为了解决这个问题,我添加了time.sleep(2),但我对lambdas还不熟悉,并且意识到在lambda中多重表达式并不是最佳实践。所以,我正在尝试将lambda转换为for循环,但遇到了一个问题。思想??这应该是一个新的stackoverflow问题吗?
apply
语句中的多步操作最好表示为普通函数,而不是lambda。这与你最初的问题有本质的不同,所以我建议你在另一篇文章中提问。但您可能会发现,首先尝试构建自己的UDF是有帮助的,这个UDF不应该太复杂,熊猫文档中已经有很多关于这个主题的内容,可以帮助您解决问题。@andrew_reece,很好的解决方案,谢谢!
                                Hospital Name                   Address  \
0                        Fortius Clinic City           London, EC4N 7BE   
1  Pinehill Hospital - Ramsay Health Care UK           Hitchin, SG4 9QZ   
2                  Spire Montefiore Hospital              Hove, BN3 1RD   
3             Chelsea & Westminster Hospital           London, SW10 9NH   
4   Nuffield Health Tunbridge Wells Hospital   Tunbridge Wells, TN2 4UL   

    Latitude  Longitude  
0  51.507322  -0.127647  
1  51.946413  -0.279165  
2  50.840871  -0.180561  
3  51.507322  -0.127647  
4  51.131528   0.278068