我有一个包含两列的数据框,如下所示:
country_code geo_coords
GB nan
nan [13.43, 52.48]
TR nan
...
我想使用
nan
列中的信息填充 country_code
中的 geo_coords
值。
要从坐标中提取国家/地区代码,我正在使用
reverse_geocoder
模块。
这是我的代码:
def from_coords_to_code(coords):
"""Find the country code of coordinates.
Args:
coords: coordinates of the point in [lon, lat] format
"""
return rg.search(coords[::-1])[0]["cc"]
sub_df["country_code"].fillna(sub_df["geo_coords"], inplace=True)
sub_df["country_code"] = sub_df["country_code"].apply(
lambda x: from_coords_to_code(x) if isinstance(x, list) else x
)
由于我有成千上万行,所以这段代码非常慢。
按照其他问题,我试图在删除
geo_coords
值后将反向地理编码应用于整个nan
列:
geo_coords = df["geo_coords"].loc[df["geo_coords"].notna()]
geo_coords_tuple = tuple(geo_coords.apply(lambda x: tuple(x[::-1])))
cc_new = rg.search(geo_coords_tuple, mode=2)
country_code = [i["cc"] for i in cc_new]
for i, j in enumerate(geo_coords.index):
df["country_code"].iloc[j] = country_code[i]
这样速度更快,但它给了我警告:
A value is trying to be set on a copy of a slice from a DataFrame
See the caveats in the documentation: https://pandas.pydata.org/pandas-docs/stable/user_guide/indexing.html#returning-a-view-versus-a-copy
sub_df["country_code"].iloc[j] = country_code[i]
我想避免这种情况,但我不确定这是一个最佳解决方案。
有什么建议可以让整个代码更高效吗?
我很高兴从“reverse_geocoder”转移到任何其他模块。
重要提示:
geo_coords
中的坐标采用geoJSON格式,即[lon,lat],这就是我反转它们的原因。
函数
rg.search()
非常慢,而且已经使用了多个核心。我能够使用 ProcessPoolExecutor
加快搜索速度,为任务添加额外的工作人员,例如:
from concurrent.futures import ProcessPoolExecutor as Pool
import pandas as pd
import reverse_geocoder as rg
from tqdm import tqdm
def process_coord(tpl):
idx, (a, b) = tpl
return idx, rg.search((b, a))[0]["cc"]
if __name__ == "__main__":
# sample dataframe:
df = pd.DataFrame(
{
"country_code": ["GB", None, "TR"] * 10_000,
"geo_coords": [None, [13.43, 52.48], None] * 10_000,
}
)
with Pool(max_workers=2) as pool:
mask = df["country_code"].isna()
data = []
for i, result in tqdm(
pool.map(process_coord, zip(df.index[mask], df.loc[mask, "geo_coords"])),
total=mask.sum(),
):
df.loc[i, "country_code"] = result
print(df)
在我的计算机 (AMD 5700x) 上,每秒执行约 17 次搜索。
5%|████████▌ | 507/10000 [00:29<09:12, 17.19it/s]