You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何比较含重复项的不同大小的Pandas DataFrame?

解决方案

可以通过统计每行的出现频次,计算两个DataFrame间的频次差异,再根据差异值重新生成包含重复项差异的结果。这种方法避免了逐行遍历,效率更高。

步骤1:定义频次统计函数

先实现一个函数,将DataFrame的每行转换为可哈希的元组,再统计每个元组的出现次数:

def get_counts(df):
    return df.apply(tuple, axis=1).value_counts()

步骤2:计算频次差异

分别统计两个DataFrame的行频次,再计算差值(不存在的行默认次数为0):

counts_df = get_counts(df)
counts_df1 = get_counts(df1)

# 计算两个频次的差值,fill_value=0处理仅在单个DF中出现的行
diff_counts = counts_df.sub(counts_df1, fill_value=0)

步骤3:生成差异结果

根据频次差的正负和绝对值,生成对应的行数据,可选择合并结果或拆分为两个独立结果:

合并所有差异行

result_rows = []
for row_tuple, count in diff_counts.items():
    if count != 0:
        # 根据次数差的绝对值重复添加该行
        result_rows.extend([row_tuple] * abs(count))

# 转换为DataFrame,列名与原DF一致
result = pd.DataFrame(result_rows, columns=df.columns)
print(result)

输出(顺序不影响需求):

Animal    Name
0    Dog    Kate
1    Dog  Robert
2  Snake    Nate

拆分为两个独立结果

如果需要分别存储df比df1多的行,以及df1比df多的行:

# df中多出的行(含重复次数差异)
df_extra = pd.DataFrame(
    [row for row, cnt in diff_counts.items() if cnt > 0 for _ in range(cnt)],
    columns=df.columns
)

# df1中多出的行(含重复次数差异)
df1_extra = pd.DataFrame(
    [row for row, cnt in diff_counts.items() if cnt < 0 for _ in range(-cnt)],
    columns=df.columns
)

print("df多出的行:")
print(df_extra)
print("\ndf1多出的行:")
print(df1_extra)

输出:

df多出的行:
  Animal    Name
0    Dog    Kate
1    Dog  Robert

df1多出的行:
  Animal  Name
0  Snake  Nate

完整可运行代码

import pandas as pd

# 创建示例DataFrame
df = pd.DataFrame({'Animal': ['Cat', 'Dog', 'Rabbit', 'Dog', 'Dog'], 'Name': ['Peter', 'Kate', 'Bas', 'Kate', 'Robert']})
df1 = pd.DataFrame({'Animal': ['Snake', 'Cat', 'Dog', 'Rabbit'], 'Name': ['Nate', 'Peter', 'Kate', 'Bas']})

def get_counts(df):
    return df.apply(tuple, axis=1).value_counts()

counts_df = get_counts(df)
counts_df1 = get_counts(df1)
diff_counts = counts_df.sub(counts_df1, fill_value=0)

# 合并结果
result_rows = []
for row_tuple, count in diff_counts.items():
    if count != 0:
        result_rows.extend([row_tuple] * abs(count))
result = pd.DataFrame(result_rows, columns=df.columns)
print("合并的差异结果:")
print(result)

# 拆分结果
df_extra = pd.DataFrame([row for row, cnt in diff_counts.items() if cnt>0 for _ in range(cnt)], columns=df.columns)
df1_extra = pd.DataFrame([row for row, cnt in diff_counts.items() if cnt<0 for _ in range(-cnt)], columns=df.columns)
print("\ndf多出的行:")
print(df_extra)
print("\ndf1多出的行:")
print(df1_extra)

原理说明

  • 用apply(tuple, axis=1)将每行转为元组,解决DataFrame行无法直接作为统计键的问题;
  • value_counts()高效统计每行的出现次数,得到“行内容-次数”的映射关系;
  • sub方法自动对齐两个频次Series的键,计算次数差,缺失键默认填充0,精准得到每行在两个DF中的数量差异;
  • 最后根据次数差的绝对值还原行数据,完全保留重复项的数量差异,且全程利用pandas向量化操作,比逐行遍历效率提升显著。

内容的提问来源于stack exchange,提问作者Nomeon

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.04 20:31:03