如何用Group by/Pivot统计国家参与符合EP条件的协议次数?
解决方案
步骤说明与代码实现
要实现你的需求,核心思路是先标记每行是否满足「至少有一个EP值≥1」,再将两个国家列转为长格式统一统计,具体代码如下:
import pandas as pd # 原始数据 df = pd.DataFrame({ "Agreement": ["Peace", "Peace", "Love", "Love", "Sun","Sun","Sun"], "country1": ["USA", "UK", "Germany", "Spain", "Italy","India","China"], "country2": ["Canada", "France", "Portugal", "Italy","India","Spain","UK"], "EP1": [1, 0, 1, 0, 0,1,1], "EP2": [0, 0, 0, 0,0,0,0], "EP3": [1, 0, 1, 0,1,1,1] }) # 1. 标记每行是否存在至少一个EP≥1 df['has_ep'] = df[['EP1', 'EP2', 'EP3']].ge(1).any(axis=1) # 2. 将country1和country2转为长格式,每个国家单独占一行 countries_long = pd.melt( df, id_vars=['has_ep'], value_vars=['country1', 'country2'], value_name='Country' ) # 3. 按国家分组,统计符合条件的次数 result = countries_long.groupby('Country')['has_ep'].sum().reset_index() # 重命名列名匹配预期输出 result.columns = ['Country', 'Agreement with at least one EP per country'] # 可选:按预期输出的国家顺序排序 target_order = ["USA", "UK", "Germany", "Spain", "Italy","India","China", "Canada","France","Portugal"] result = result.set_index('Country').loc[target_order].reset_index() print(result)
代码解释
- 标记行条件:用
ge(1).any(axis=1)判断每行的EP1/EP2/EP3是否有至少一个值≥1,生成布尔列has_ep; - 长格式转换:通过
pd.melt将原本的country1和country2列合并为一列Country,确保每个国家的每一次参与都单独成一行; - 分组统计:按
Country分组后对has_ep求和(布尔值True等价于1,False等价于0),直接得到每个国家的符合条件次数; - 顺序调整:最后按你给出的预期国家顺序重新排序,保证输出结构完全匹配。
运行上述代码后,输出结果与你期望的DataFrame完全一致。
内容的提问来源于stack exchange,提问作者jhonccc
相关产品推荐
相关产品推荐

