如何从纬度和经度坐标列表中获取城市、州和国家/地区?

Nic*_*ick 6 python latitude-longitude pandas

我有 500,000 个纬度和经度坐标列表,如下所示:

Latitude   Longitude  
42.022506  -88.168156  
41.877445  -87.723846  
29.986801  -90.166314  
Run Code Online (Sandbox Code Playgroud)

我希望使用 python 来获取新列中每个坐标的城市、州和国家/地区,如下所示:

Latitude   Longitude   City        State   Country
42.022506  -88.168156  Streamwood  IL      United States
41.877445  -87.723846  Chicago     IL      United States
29.986801  -90.166314  Metairie    LA      United States
Run Code Online (Sandbox Code Playgroud)

这么大的数据集,如何用Python实现呢?我听说过 Google 的 API、Nominatim 的 API 和 Geopy 包。

我如何才能将所有行运行到这段代码中?现在我必须在最后一行手动输入纬度和经度。

import csv 
import pandas as pd
import numpy as np
import math
from geopy.geocoders import Nominatim

input_file = "Lat-Log.csv" # file contains ID, Latitude, Longitude
output_file = "output.csv"
df = pd.read_csv(input_file) 

geolocator = Nominatim(user_agent="geoapiExercises")
def city_state_country(coord):
    location = geolocator.reverse(coord, exactly_one=True)
    address = location.raw['address']
    city = address.get('city', '')
    state = address.get('state', '')
    country = address.get('country', '')
    return city, state, country
print(city_state_country("47.470706, -99.704723"))
Run Code Online (Sandbox Code Playgroud)

输出给我(“鲍登”,“北达科他州”,“美国”)。我希望用我的列(纬度和经度)替换坐标以遍历我的列表。如何将我的列输入到代码中以运行整个文档?

Nic*_*ell 8

您想要在每一行上运行一个函数,这可以使用apply()来完成。

有两个复杂之处,即您想要 1) 向函数提供多个参数,2) 返回多个结果。

这些问题解释了如何做这些事情:

以下是如何调整您的代码来执行此操作:

import pandas as pd
import io
from geopy.geocoders import Nominatim
geolocator = Nominatim(user_agent="geoapiExercises")

s = """Latitude   Longitude  
42.022506  -88.168156  
41.877445  -87.723846  
29.986801  -90.166314"""

df = pd.read_csv(io.StringIO(s), delim_whitespace=True)

def city_state_country(row):
    coord = f"{row['Latitude']}, {row['Longitude']}"
    location = geolocator.reverse(coord, exactly_one=True)
    address = location.raw['address']
    city = address.get('city', '')
    state = address.get('state', '')
    country = address.get('country', '')
    row['city'] = city
    row['state'] = state
    row['country'] = country
    return row

df = df.apply(city_state_country, axis=1)
print(df)
Run Code Online (Sandbox Code Playgroud)

(我用数据帧的内联定义替换了您的 read_csv() 调用。忽略它。这对示例来说并不重要。我这样做是为了使示例独立。)

city_state_country()数据帧的每一行都会调用该函数。(该axis=1参数使 apply() 使用行而不是列运行。)该函数获取纬度和经度,并执行查询。然后,它修改该行以包含查询中的信息。

这会得到以下结果:

    Latitude  Longitude     city      state        country
0  42.022506 -88.168156            Illinois  United States
1  41.877445 -87.723846  Chicago   Illinois  United States
2  29.986801 -90.166314           Louisiana  United States
Run Code Online (Sandbox Code Playgroud)

与您的示例不同,但 Nominatim 似乎没有返回两个坐标的城市。(它称它们为城镇,而不是城市。)

  • @Nick我会创建一个单独的职位和位置表,并且只请求唯一的职位,这样您就不会重复请求。事实上,您可能应该过滤彼此相距数百英尺的位置,假设它们实际上位于同一城市,因此不需要请求。然后从该查找数据库填写完整数据库。 (2认同)