世界地図にプロットしたい約300のIPアドレスのリストがあります。Pythonでそれを行う方法を大まかに説明できますか?
編集:質問の視覚化部分にも興味があります
世界地図にプロットしたい約300のIPアドレスのリストがあります。Pythonでそれを行う方法を大まかに説明できますか?
編集:質問の視覚化部分にも興味があります
hostip.infoAPIを使用できます。例えば:
http://api.hostip.info/get_html.php?ip=64.233.160.0
したがって、を使用するPythonコードは次のurllib2
ようになります。
import urllib2
f = urllib2.urlopen("http://api.hostip.info/get_html.php?ip=64.233.160.0")
data = f.read()
f.close()
次に、返された結果からデータを取得します。
経度と緯度が必要な場合は、次のposition=true
フラグを使用してください。
http://api.hostip.info/get_html.php?ip=64.233.160.0&position=true
無料版と有料版の両方があるGeoIPを使用できます。便利なPythonAPIもあります。
これが、 IPアドレスを含むデータフレームを指定して地理的位置情報を返すPython3.xでの私のソリューションです。ベクトル化されたpd.series/dataframeでの関数の効率的な並列化されたアプリケーションは、進むべき道です。
マップ上にレコードをプロットするには、緯度と経度の情報をサブセット化した後、Google MapsApiやtableauなどの適切なMappingAPIを使用すると、データの視覚化に役立ちます。
2つの人気のあるライブラリのパフォーマンスを、場所を返すために対比します。
TLDR:geolite2メソッドを使用します。
1. ライブラリgeolite2
からのパッケージgeolite2
入力
# !pip install maxminddb-geolite2
import time
from geolite2 import geolite2
geo = geolite2.reader()
df_1 = train_data.loc[:50,['IP_Address']]
def IP_info_1(ip):
try:
try:
x = geo.get(ip)
except ValueError: #Faulty IP value
return np.nan
try:
return x['country']['names']['en'] if x is not None else np.nan
except KeyError: #Faulty Key value
return np.nan
s_time = time.time()
# map IP --> country
#apply(fn) applies fn. on all pd.series elements
df_1['country'] = df_1.loc[:,'IP_Address'].apply(IP_info_1)
print(df_1.head(), '\n')
print('Time:',str(time.time()-s_time)+'s \n')
print(type(geo.get('48.151.136.76')))
出力
IP_Address country
0 48.151.136.76 United States
1 94.9.145.169 United Kingdom
2 58.94.157.121 Japan
3 193.187.41.186 Austria
4 125.96.20.172 China
Time: 0.09906983375549316s
<class 'dict'>
2. ライブラリDbIpCity
からのパッケージip2geotools
入力
# !pip install ip2geotools
import time
s_time = time.time()
from ip2geotools.databases.noncommercial import DbIpCity
df_2 = train_data.loc[:50,['IP_Address']]
def IP_info_2(ip):
try:
return DbIpCity.get(ip, api_key = 'free').country
except:
return np.nan
df_2['country'] = df_2.loc[:, 'IP_Address'].apply(IP_info_2)
print(df_2.head())
print('Time:',str(time.time()-s_time)+'s')
print(type(DbIpCity.get('48.151.136.76',api_key = 'free')))
出力
IP_Address country
0 48.151.136.76 US
1 94.9.145.169 GB
2 58.94.157.121 JP
3 193.187.41.186 AT
4 125.96.20.172 CN
Time: 80.53318452835083s
<class 'ip2geotools.models.IpLocation'>
大きな時間差が出力のデータ構造に起因する可能性がある理由、つまり辞書からの直接サブセット化は、特定のip2geotools.models.IpLocationオブジェクトからのインデックス作成よりもはるかに効率的であるように思われ ます。
また、最初のメソッドの出力は、ジオロケーションデータを含む辞書であり、必要な情報を取得するためにそれぞれサブセット化されます。
x = geolite2.reader().get('48.151.136.76')
print(x)
>>>
{'city': {'geoname_id': 5101798, 'names': {'de': 'Newark', 'en': 'Newark', 'es': 'Newark', 'fr': 'Newark', 'ja': 'ニューアーク', 'pt-BR': 'Newark', 'ru': 'Ньюарк'}},
'continent': {'code': 'NA', 'geoname_id': 6255149, 'names': {'de': 'Nordamerika', 'en': 'North America', 'es': 'Norteamérica', 'fr': 'Amérique du Nord', 'ja': '北アメリカ', 'pt-BR': 'América do Norte', 'ru': 'Северная Америка', 'zh-CN': '北美洲'}},
'country': {'geoname_id': 6252001, 'iso_code': 'US', 'names': {'de': 'USA', 'en': 'United States', 'es': 'Estados Unidos', 'fr': 'États-Unis', 'ja': 'アメリカ合衆国', 'pt-BR': 'Estados Unidos', 'ru': 'США', 'zh-CN': '美国'}},
'location': {'accuracy_radius': 1000, 'latitude': 40.7355, 'longitude': -74.1741, 'metro_code': 501, 'time_zone': 'America/New_York'},
'postal': {'code': '07102'},
'registered_country': {'geoname_id': 6252001, 'iso_code': 'US', 'names': {'de': 'USA', 'en': 'United States', 'es': 'Estados Unidos', 'fr': 'États-Unis', 'ja': 'アメリカ合衆国', 'pt-BR': 'Estados Unidos', 'ru': 'США', 'zh-CN': '美国'}},
'subdivisions': [{'geoname_id': 5101760, 'iso_code': 'NJ', 'names': {'en': 'New Jersey', 'es': 'Nueva Jersey', 'fr': 'New Jersey', 'ja': 'ニュージャージー州', 'pt-BR': 'Nova Jérsia', 'ru': 'Нью-Джерси', 'zh-CN': '新泽西州'}}]}