如何统计三个DataFrame未共享条目及连接后被排除条目数?
最优Pandas实现方案:统计未共享条目与连接排除条目
嘿,针对你的需求,我整理了一套高效的Pandas代码方案,同时会帮你理清两个统计指标的定义,避免混淆~
先明确前提假设
假设我们有三个原始DataFrame:df1、df2、df3,且已经通过pd.merge(或类似方法)基于Country Name列完成了连接,得到了最终的连接结果merged_df。另外默认每个DataFrame中的Country Name可能存在重复条目(如果你的数据是每个国家唯一一行,代码依然适用,只是计算逻辑会自动适配)。
1. 统计三个原DataFrame中未共享的条目总数
这里的「未共享条目」指的是Country Name未同时出现在三个原始DataFrame中的所有条目(包括只在1个DF出现、或只在2个DF出现的条目)。
实现代码
import pandas as pd # 获取每个DF中唯一的国家集合 set1 = set(df1['Country Name'].unique()) set2 = set(df2['Country Name'].unique()) set3 = set(df3['Country Name'].unique()) # 计算三个DF共享的国家集合(同时出现在三个DF中的国家) shared_countries = set1 & set2 & set3 # 统计每个DF中未共享的条目数,再求和 unshared_total = ( len(df1[~df1['Country Name'].isin(shared_countries)]) + len(df2[~df2['Country Name'].isin(shared_countries)]) + len(df3[~df3['Country Name'].isin(shared_countries)]) ) print(f"三个原DF中未共享的条目总数:{unshared_total}")
性能优化点
- 使用
unique()+set的组合快速获取国家集合,比逐行判断高效 - 利用Pandas的向量化操作
isin()筛选数据,避免循环,大幅提升速度
2. 统计连接操作中被排除的原DataFrame条目数量
这里的「被排除条目」指的是原始DF中没有被包含到最终连接结果merged_df中的所有条目。这个统计需要结合你使用的连接类型(内连接/外连接等)来计算:
通用实现方案(适配所有连接类型)
# 先获取连接结果中包含的所有Country Name(去重) merged_countries = set(merged_df['Country Name'].unique()) # 统计每个DF中未出现在连接结果里的条目数,再求和 excluded_total = ( len(df1[~df1['Country Name'].isin(merged_countries)]) + len(df2[~df2['Country Name'].isin(merged_countries)]) + len(df3[~df3['Country Name'].isin(merged_countries)]) ) print(f"连接操作中被排除的原DF条目数量:{excluded_total}")
针对内连接的简化计算(如果确定是内连接)
如果你的连接是内连接(how='inner'),那么merged_countries其实等于shared_countries,此时可以直接复用第一部分的结果:
# 内连接下,被排除的条目数等于未共享条目总数 excluded_total_inner = unshared_total print(f"内连接下被排除的条目数量:{excluded_total_inner}")
完整示例代码
# 模拟测试数据 data1 = {'Country Name': ['USA', 'Canada', 'UK', 'China'], 'Data1': [100, 200, 300, 400]} data2 = {'Country Name': ['USA', 'Canada', 'Germany', 'China'], 'Data2': [150, 250, 350, 450]} data3 = {'Country Name': ['USA', 'Japan', 'UK', 'China'], 'Data3': [120, 220, 320, 420]} df1 = pd.DataFrame(data1) df2 = pd.DataFrame(data2) df3 = pd.DataFrame(data3) # 执行内连接 merged_df = pd.merge(pd.merge(df1, df2, on='Country Name'), df3, on='Country Name') # 计算未共享条目总数 set1 = set(df1['Country Name'].unique()) set2 = set(df2['Country Name'].unique()) set3 = set(df3['Country Name'].unique()) shared_countries = set1 & set2 & set3 unshared_total = len(df1[~df1['Country Name'].isin(shared_countries)]) + len(df2[~df2['Country Name'].isin(shared_countries)]) + len(df3[~df3['Country Name'].isin(shared_countries)]) # 计算被排除条目总数 merged_countries = set(merged_df['Country Name'].unique()) excluded_total = len(df1[~df1['Country Name'].isin(merged_countries)]) + len(df2[~df2['Country Name'].isin(merged_countries)]) + len(df3[~df3['Country Name'].isin(merged_countries)]) print(f"未共享条目总数:{unshared_total}") # 输出:4(Canada、UK、Germany、Japan各1条) print(f"被排除条目总数:{excluded_total}") # 输出:4(和未共享总数一致,因为是内连接)
内容的提问来源于stack exchange,提问作者AustinMiller
相关产品推荐
相关产品推荐

