pandas 确定来自两个 Dataframe python的公共行数(或行的确切交集)(例外情况)

snvhrwxg  于 2023-01-11  发布在  Python
关注(0)|答案(1)|浏览(108)

我试图在python中得到两个Pandasdf之间的行的确切交集。我可以在merge()函数的帮助下完成。
当前逻辑:

import pandas as pd

# input df's
data1 = pd.DataFrame({'x1':[1,2,3,4,5,3],                   
                      'x3':[9,8,7,6,6,8]})

data3 = pd.DataFrame({'x1':[2,1,2,6,4,4,5],                   
                      'x3':[8,3,9,8,7,6,6]})

data_13 = data1.merge(data3,                                  # Merge DataFrames with indicator 
                        indicator = True,
                        how = 'outer')
print(data_13)                                               

## common rows (the appears in both data1 and data3)
data_13_diff = data_13.loc[lambda x : x['_merge'] == 'both'] 
print(data_13_diff)   
                                        
## count the number of rows in data_13_diff
print('count:',data_13_diff.shape[0])

输出:

x1  x3 _merge
1   2   8   both
3   4   6   both
4   5   6   both
count: 3

正如预期的那样,输出显示data1和data3中的公共行(相交行
但是,当一个df中有多个相同值的行时,会遇到此异常。例如:

# input df's
data1 = pd.DataFrame({'x1':[1,2,3,4,5,2],                    
                      'x3':[9,8,7,6,6,8]})

data3 = pd.DataFrame({'x1':[1,2,2,4,4,5,3],                   
                      'x3':[3,9,8,7,6,6,8]})

输出结果为:

x1  x3 _merge
1   2   8   both
2   2   8   both
4   4   6   both
5   5   6   both
count: 4

即使只有一个示例在data3中,当前逻辑输出2,例如data1具有2个(2,8)。这不是任务所必需的。这里所需的输出应该是"两个df的精确交集",即作为(2,8)应该只出现一次,就像其他公共条目(4,6)和(5,6)一样。这将导致两个df中正确的3个公共行计数。
当输入为:

# input df's
data1 = pd.DataFrame({'x1':[1,2,3,4,5,2],                    
                      'x3':[9,8,7,6,6,8]})

data3 = pd.DataFrame({'x1':[2,1,2,2,4,4,5],                   
                      'x3':[8,3,9,8,7,6,6]})

这里,data1和data3都有两个(2,8)的示例。因此,所需的输出应该是总共4个公共行(有两个(2,8)的示例,(4,6)和(5,6)各一个)。而当前逻辑得到了4个(2,8)的示例!!!

x1  x3 _merge
1   2   8   both
2   2   8   both
3   2   8   both
4   2   8   both
6   4   6   both
7   5   6   both
count: 6

如果有人能帮助我在逻辑上解决这个问题,我将非常感激。任何替代的建议/反馈也欢迎。:)
干杯!

bvn4nwqk

bvn4nwqk1#

如果联接列中存在重复值,则合并将执行笛卡尔乘积。要避免这种情况,可以创建一个虚拟计数列,以便在合并前删除重复项。以最后一种情况为例:

data1['cnt'] = data1.groupby(data1.columns.tolist()).x1.cumcount()
data3['cnt'] = data3.groupby(data3.columns.tolist()).x1.cumcount()

data1.merge(data3, how='inner')
   x1  x3  cnt
0   2   8    0
1   4   6    0
2   5   6    0
3   2   8    1

相关问题