有没有办法合并两个数据帧,只保留一定数量的出现次数?

Rak*_*sha 2 python merge pandas

例如.如果我有两个数据集:

df1 = pd.DataFrame([[1, 2.1, 5, 0, 'a'], [7, 2.3, 5, 1, 'b'], [0, 2, 0, 1, 'c'], [9, 4, 4, 1, 'd']],columns=list('ABCDE'))
df2 = pd.DataFrame([[3, 2, 5, 0, 1, 2], [3, 2.4, 5, 1, 9, 9], [9, 9, 5, 9, 4, 5], [0, 2, 5, 0, 1, 1], [1, 4, 4, 3, 8, 0]],columns=list('xBCyzw'))
Run Code Online (Sandbox Code Playgroud)

我想基于列'B'和'C'合并它们,但我只希望合并行的实例与df1中的实例一样多.

换句话说,我想在df2中找到基于'B'和'C'匹配df1中的行的行,并将df2中的列附加到df1.

我现在拥有的是

print(pd.merge(np.round(df2), np.round(df1), on=['B', 'C'], how='inner', left_index = True))
Run Code Online (Sandbox Code Playgroud)

哪个输出

   x    B  C  y  z  w  A  D  E
0  3  2.0  5  0  1  2  1  0  a
1  3  2.0  5  0  1  2  7  1  b
0  3  2.0  5  1  9  9  1  0  a
1  3  2.0  5  1  9  9  7  1  b
0  0  2.0  5  0  1  1  1  0  a
1  0  2.0  5  0  1  1  7  1  b
3  1  4.0  4  3  8  0  9  1  d
Run Code Online (Sandbox Code Playgroud)

但由于在df1中只有两行B = 2,C = 5,我希望在合并结果中只有两行.df2中的三个匹配行中的哪一行合并无关紧要.

例:

   x    B  C  y  z  w  A  D  E
0  3  2.0  5  0  1  2  1  0  a
1  3  2.0  5  0  1  2  7  1  b
3  1  4.0  4  3  8  0  9  1  d
Run Code Online (Sandbox Code Playgroud)

要么:

   x    B  C  y  z  w  A  D  E
0  3  2.0  5  1  9  9  1  0  a
1  3  2.0  5  1  9  9  7  1  b
3  1  4.0  4  3  8  0  9  1  d
Run Code Online (Sandbox Code Playgroud)

要么:

   x    B  C  y  z  w  A  D  E
0  0  2.0  5  0  1  1  1  0  a
1  0  2.0  5  0  1  1  7  1  b
3  1  4.0  4  3  8  0  9  1  d
Run Code Online (Sandbox Code Playgroud)

除了循环之外,我想不出更好的方法.

有任何想法吗?

cs9*_*s95 5

首先,圆形df1df2:

i, j = map(np.round, [df1, df2])
Run Code Online (Sandbox Code Playgroud)

接下来,合并BC:

v = pd.merge(i, j, on=['B', 'C'], how='inner', left_index=True)
Run Code Online (Sandbox Code Playgroud)

添加虚拟计数列i和合并结果:

v['Count'] = v.groupby(['B', 'C']).cumcount()
i['Count'] = i.groupby(['B', 'C']).cumcount()
Run Code Online (Sandbox Code Playgroud)

i使用新计数列执行第二次合并.

v.merge(i[['B','C','Count']], on=['B','C','Count']).drop('Count', 1)

   A    B  C  D  E  x  y  z  w
0  1  2.0  5  0  a  3  0  1  2
1  1  2.0  5  0  a  3  1  9  9
2  9  4.0  4  1  d  1  3  8  0
Run Code Online (Sandbox Code Playgroud)