如何基于两个DataFrame的多条件计算国际组织成员国平均距离
实现方案
步骤1:预处理df2,转换为长表格式
你当前的df2是宽表结构,每列对应一个国家,先转换为「年份-国际组织-成员国」的长表,过滤出成员身份为1的记录:
import pandas as pd # 预处理df2:转长表+筛选成员国 df2_long = df2.melt( id_vars=["year", "ioname"], var_name="country", value_name="is_member" ).query("is_member == 1")
步骤2:按年份+国际组织分组计算平均距离
对每个分组的成员国列表,匹配df1中两国都属于该组织当前年份成员国的距离记录,再求平均值:
def calc_mean_dist(member_countries, df_dist): # 筛选两国都在成员国列表中的距离记录 mask = df_dist["countryA"].isin(member_countries) & df_dist["countryB"].isin(member_countries) return df_dist.loc[mask, "dist"].mean() # 分组计算得到最终结果 result = df2_long.groupby(["year", "ioname"])["country"].apply( lambda x: calc_mean_dist(x, df1) ).reset_index(name="mean_distance")
注意事项
- 如果df1中同时存在
(A,B)和(B,A)的重复无向配对,计算前可先去重:
# 去重df1的无向国家配对 df1[["min_country", "max_country"]] = df1[["countryA", "countryB"]].apply(sorted, axis=1, result_type="expand") df1 = df1.drop_duplicates(subset=["min_country", "max_country"]).drop(columns=["min_country", "max_country"])
- 需保证两个表的国家名称拼写完全一致,没有译名差异,否则会出现匹配失效的问题。
- 若某组织当年成员国数量小于2,计算得到的
mean_distance会是NaN,可通过result = result.dropna(subset=["mean_distance"])过滤掉这类无效记录。
内容的提问来源于stack exchange,提问作者user14237226
相关产品推荐
相关产品推荐

