Pandas合并含重复行的DataFrame:匹配相同行并堆叠差异行
合并两个DataFrame:匹配相同行并堆叠不匹配行
场景描述
现有两个DataFrame,部分行除某一列(示例中为attempts)外完全相同,需要实现:
- 匹配完全相同的行(除目标列外),保留目标列的有效值(示例中取df2的
attempts值) - 两边独有的行直接垂直堆叠到结果中
示例数据:
import pandas as pd df1 = pd.DataFrame({ 'id': [0, 1, 2], 'account': ['a', 'b', 'c'], 'details': [ [{'a': 'b'}, {'c': 'd'}], [{'e': 'f'}, {'g': 'h'}], [{'a': 'b'}, {'c': 'd'}] ] }) df2 = pd.DataFrame({ 'id': [0, 1, 3], 'account': ['a', 'b', 'g'], 'details': [ [{'a': 'b'}, {'c': 'd'}], [{'e': 'f'}, {'g': 'h'}], [{'e': 'f'}, {'g': 'h'}] ], 'attempts': [4, 5, 6] })
期望结果:
result = pd.DataFrame({ 'id': [0, 1, 2, 3], 'account': ['a', 'b', 'c', 'g'], 'details': [ [{'a': 'b'}, {'c': 'd'}], [{'e': 'f'}, {'g': 'h'}], [{'a': 'b'}, {'c': 'd'}], [{'e': 'f'}, {'g': 'h'}], ], 'attempts': [4, 5, None, 6] })
解决方案
通过统一列结构 + 合并去重的方式即可实现需求:
步骤1:统一两个DataFrame的列结构
给df1添加缺失的attempts列,值设为None:
df1['attempts'] = None
步骤2:合并两个DataFrame
使用pd.concat将两个DataFrame垂直堆叠:
combined = pd.concat([df1, df2], ignore_index=True)
步骤3:去重并保留有效值
以id、account、details作为唯一标识,先按attempts排序让非空值靠前,再去重保留每组第一行(即优先保留df2的有效attempts值):
combined_sorted = combined.sort_values('attempts', ascending=False, na_position='last') result = combined_sorted.drop_duplicates(subset=['id', 'account', 'details'], keep='first').reset_index(drop=True)
完整代码
import pandas as pd df1 = pd.DataFrame({ 'id': [0, 1, 2], 'account': ['a', 'b', 'c'], 'details': [ [{'a': 'b'}, {'c': 'd'}], [{'e': 'f'}, {'g': 'h'}], [{'a': 'b'}, {'c': 'd'}] ] }) df2 = pd.DataFrame({ 'id': [0, 1, 3], 'account': ['a', 'b', 'g'], 'details': [ [{'a': 'b'}, {'c': 'd'}], [{'e': 'f'}, {'g': 'h'}], [{'e': 'f'}, {'g': 'h'}] ], 'attempts': [4, 5, 6] }) # 统一列结构 df1['attempts'] = None # 合并并排序 combined = pd.concat([df1, df2], ignore_index=True) combined_sorted = combined.sort_values('attempts', ascending=False, na_position='last') # 去重得到结果 result = combined_sorted.drop_duplicates(subset=['id', 'account', 'details'], keep='first').reset_index(drop=True) print(result)
运行后即可得到符合要求的结果。
内容的提问来源于stack exchange,提问作者Football52
相关产品推荐
相关产品推荐

