2017-12-09 5 views
0

病院の名前と住所の2つの列を持つデータフレームがあり、緯度と経度を見つけるために各住所を反復したいと思います。私のコードは、データフレームの最初の行を取っているようだと私は座標を見つけるためにアドレスを選択するように見えることはできません。パンダのデータフレーム上でジオロケーションを反復する

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 

現在のデータは、(1病院の例)のようになります。

Hospital Name |Address   
Fulwood Hospital|Preston, PR2 9SZ 

私が達成しようとしている最終的な出力は次のようになります。

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

あなたの現在および予想される出力と一緒にいくつかのサンプルデータを入力してください。 – Cleb

答えて

1

ここにはいくつかの問題があるようです。あなたが提供された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)あなたのデータフレームの列名が本当にHospital nameAddressている場合は、geocode()への呼び出しでitem.Addressを使用する必要があります。
ちょうどitemを使用すると、Hospital nameAddressの両方が表示されます。

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)あなたのデータフレームが2つだけの列を持っていることを指摘しました。それが当てはまる場合、df["Latitude"]df["Longitude"]で操作を実行しようとすると、KeyErrorが存在するため、それらは存在しません。

(3)Addressカラムapply()を使用するiterrows()より明確かもしれません。
これは文章的な点であり、議論の余地があることに注意してください。 (最初の2点は、実際のエラーです。)例えば

、提供された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 
+0

これは、ジオコーダがタイムアウトして1秒あたり1リクエスト以上を実行しない限り、ある程度機能します。これに対処するために、私はtime.sleep(2)を追加していますが、lambdaには新しく、複数の式はラムダではベストプラクティスではないことを認識しています。だから、ラムダをforループに変換する練習をしようとしていますが、問題が発生しました。思考?これは新しいスタックオーバーフローの質問ですか? – MartyB

+0

'apply'ステートメントのマルチステップ操作は、lambdasではなく通常の関数として表現するのが最適です。あなたの最初の質問とはかなり異なっているので、私は別の投稿で尋ねることをお勧めします。しかし、あなた自身のUDFを最初に構築しようとすると役に立つでしょう。これはあまり複雑すぎるべきではありません。既にこのトピックに多くのパンダドキュメントやSOがあります。 –

関連する問題