私はdfを持っています:
import pandas as pd
import numpy as np
import datetime as DT
import hmac
from geopy.geocoders import Nominatim
from geopy.distance import vincenty
df
city_name state_name county_name
0 WASHINGTON DC DIST OF COLUMBIA
1 WASHINGTON DC DIST OF COLUMBIA
2 WASHINGTON DC DIST OF COLUMBIA
3 WASHINGTON DC DIST OF COLUMBIA
4 WASHINGTON DC DIST OF COLUMBIA
5 WASHINGTON DC DIST OF COLUMBIA
6 WASHINGTON DC DIST OF COLUMBIA
7 WASHINGTON DC DIST OF COLUMBIA
8 WASHINGTON DC DIST OF COLUMBIA
9 WASHINGTON DC DIST OF COLUMBIA
以下のデータフレームのいずれかの列の緯度と経度の座標を取得したいと思います。ドキュメント( http://geopy.readthedocs.org/en/latest/#data )は、個々の場所のドキュメントを操作するときに非常に簡単です。
>>> from geopy.geocoders import Nominatim
>>> geolocator = Nominatim()
>>> location = geolocator.geocode("175 5th Avenue NYC")
>>> print(location.address)
Flatiron Building, 175, 5th Avenue, Flatiron, New York, NYC, New York, ...
>>> print((location.latitude, location.longitude))
(40.7410861, -73.9896297241625)
>>> print(location.raw)
{'place_id': '9167009604', 'type': 'attraction', ...}
ただし、この関数をdfの各行に適用して、新しい列を作成したいと思います。私は以下を試しました
df['city_coord'] = geolocator.geocode(lambda row: 'state_name' (row))
しかし、次のようになるため、コードに何かが欠けていると思います。
city_name state_name county_name coordinates
0 WASHINGTON DC DIST OF COLUMBIA None
1 WASHINGTON DC DIST OF COLUMBIA None
2 WASHINGTON DC DIST OF COLUMBIA None
3 WASHINGTON DC DIST OF COLUMBIA None
4 WASHINGTON DC DIST OF COLUMBIA None
5 WASHINGTON DC DIST OF COLUMBIA None
6 WASHINGTON DC DIST OF COLUMBIA None
7 WASHINGTON DC DIST OF COLUMBIA None
8 WASHINGTON DC DIST OF COLUMBIA None
9 WASHINGTON DC DIST OF COLUMBIA None
うまくいけばLambda関数を使用してこのようなものが欲しいです:
city_name state_name county_name city_coord
0 WASHINGTON DC DIST OF COLUMBIA 38.8949549, -77.0366456
1 WASHINGTON DC DIST OF COLUMBIA 38.8949549, -77.0366456
2 WASHINGTON DC DIST OF COLUMBIA 38.8949549, -77.0366456
3 WASHINGTON DC DIST OF COLUMBIA 38.8949549, -77.0366456
4 WASHINGTON DC DIST OF COLUMBIA 38.8949549, -77.0366456
5 WASHINGTON DC DIST OF COLUMBIA 38.8949549, -77.0366456
6 WASHINGTON DC DIST OF COLUMBIA 38.8949549, -77.0366456
7 WASHINGTON DC DIST OF COLUMBIA 38.8949549, -77.0366456
8 WASHINGTON DC DIST OF COLUMBIA 38.8949549, -77.0366456
9 WASHINGTON DC DIST OF COLUMBIA 38.8949549, -77.0366456
10 GLYNCO GA GLYNN 31.2224512, -81.5101023
私はどんな助けにも感謝します。座標を取得したら、それらをマッピングしたいと思います。座標をマッピングするための推奨リソースも大歓迎です。ありがとう
apply
を呼び出して、次のようにすべての行で実行する関数を渡すことができます。
_In [9]:
geolocator = Nominatim()
df['city_coord'] = df['state_name'].apply(geolocator.geocode)
df
Out[9]:
city_name state_name county_name \
0 WASHINGTON DC DIST OF COLUMBIA
1 WASHINGTON DC DIST OF COLUMBIA
city_coord
0 (District of Columbia, United States of Americ...
1 (District of Columbia, United States of Americ...
_
次に、緯度と経度の属性にアクセスできます。
_In [16]:
df['city_coord'] = df['city_coord'].apply(lambda x: (x.latitude, x.longitude))
df
Out[16]:
city_name state_name county_name city_coord
0 WASHINGTON DC DIST OF COLUMBIA (38.8937154, -76.9877934586326)
1 WASHINGTON DC DIST OF COLUMBIA (38.8937154, -76.9877934586326)
_
または、apply
を2回呼び出して、ワンライナーでそれを行います。
_In [17]:
df['city_coord'] = df['state_name'].apply(geolocator.geocode).apply(lambda x: (x.latitude, x.longitude))
df
Out[17]:
city_name state_name county_name city_coord
0 WASHINGTON DC DIST OF COLUMBIA (38.8937154, -76.9877934586326)
1 WASHINGTON DC DIST OF COLUMBIA (38.8937154, -76.9877934586326)
_
また、あなたの試みgeolocator.geocode(lambda row: 'state_name' (row))
は何もしなかったので、なぜあなたはNone
値でいっぱいの列を持っているのですか?
[〜#〜]編集[〜#〜]
@lebはここで興味深い点を示しています。重複する値が多数ある場合は、一意の値ごとにジオコーディングしてから、これを追加する方がパフォーマンスが高くなります。
_In [38]:
states = df['state_name'].unique()
d = dict(Zip(states, pd.Series(states).apply(geolocator.geocode).apply(lambda x: (x.latitude, x.longitude))))
d
Out[38]:
{'DC': (38.8937154, -76.9877934586326)}
In [40]:
df['city_coord'] = df['state_name'].map(d)
df
Out[40]:
city_name state_name county_name city_coord
0 WASHINGTON DC DIST OF COLUMBIA (38.8937154, -76.9877934586326)
1 WASHINGTON DC DIST OF COLUMBIA (38.8937154, -76.9877934586326)
_
したがって、上記はunique
を使用してすべての一意の値を取得し、それらからdictを作成してから、map
を呼び出してルックアップを実行し、座標を追加します。これは、行をジオコーディングするよりも効率的です。賢い
@EdChumの答えに賛成して受け入れてください、私はこれに追加したかっただけです。彼の方法は完璧に機能しますが、個人的な経験から、いくつかのことを共有したいと思います。
ジオコーディングを扱う場合、複数の都市と州の組み合わせが繰り返されている場合、ジオコーディングを取得するために1つだけを送信し、残りを以下の他の行に複製する方がはるかに高速です。
これは非常に大きなデータに役立ちます。2つの方法で実行できます。
drop_duplicate
_を使用して実行できますgroup_by
_を都市と州の組み合わせで保持する場合は、最初の行にhead(1)
を呼び出してジオコーディングを適用し、残りの行に複製します。理由は、Nominatimを呼び出すたびに、同じ都市/州を続けてキューに入れていたとしても、小さな遅延の問題が発生するためです。このsmallデータが大きくなるとレイテンシーが悪化し、応答が大幅に遅れてタイムアウトになる可能性があります。
繰り返しますが、これはすべて個人的に対処することによるものです。それが今あなたに利益をもたらさないならば、ただ将来の使用のために心に留めておいてください。