合并:丢弃左右数据框中都不存在的重复项?
Merge: discard duplicates that do not exist in both left and right dataframes?
我有来自两个来源的相同数据。两者都在 pandas DataFrame
秒。一些事情正在发生:
- 由于某些旧软件的读取错误,来自
source 1
(左)的数据只是来自source 2
(右)的数据的一个子集。
- 来自
source 2
的数据多了一列。
- 两个数据源都可能包含有效的重复值。
- 两者之间没有共享唯一键。
期望的结果
- 我想合并两者,保持交集。
- 仅当两个数据框中都存在重复项时才应保留重复项。这似乎很难,因为两个数据帧的长度不同并且没有共享唯一键。
- 第二个数据框中的额外列应该在新的合并数据框中。
工作示例/我尝试过的
这是一个简单的例子:
df1 = pd.DataFrame(
{ # last entry a duplicate of the first
'var1' : [1, 2, 3, 1,],
'var2' : ['a', 'b', 'c', 'a']
}
)
df2 = pd.DataFrame(
{ # last two entries duplicates of first two.
'cat': [1, 2, 3, 4, 1, 2],
'var1' : [1, 2, 3, 4, 1, 2],
'var2' : ['a', 'b', 'c', 'd', 'a', 'b']
}
)
merged = pd.merge(df1, df2, on=["var1", "var2"], how="inner")
merged
结果:
# - indicates undesired duplicates
var1 var2 cat
0 1 a 1
1 1 a 1
2 1 a 1 #
3 1 a 1 #
4 2 b 2
5 2 b 2 #
6 3 c 3
但我期待的是(顺序无关紧要):
var1 var2 cat
0 1 a 1
1 1 a 1
2 2 b 2
3 3 c 3
我查看了删除重复项,但它不会歧视并破坏有价值的信息。
merged.drop_duplicates()
var1 var2 cat
0 1 a 1
4 2 b 2
6 3 c 3
我的一个想法是想出一种方法,让两个以上的二进制列在合并之前标识源,并删除两个列都不正确的任何行。
var1 var2 cat src1 src2
0 1 a 1 1 1
1 1 a 1 1 1
2 1 a 1 0 1 # drop
3 1 a 1 0 1 # drop
4 2 b 2 1 1
5 2 b 2 0 1 # drop
6 3 c 3 1 1
但是,我不确定如何在合并期间实现这种标记(如果可能的话)。
问题:
所以,简而言之,问题是 “如何合并两个表,仅当它们存在于两个表中时才允许保留重复项”?
尝试与枚举合并:
key_cols = ['var1','var2']
(df1.assign(enum=df1.groupby(key_cols).cumcount())
.merge(df2.assign(enum=df2.groupby(key_cols).cumcount()),
on=['enum'] + key_cols, how='inner')
.drop('enum', axis=1)
)
输出:
var1 var2 cat
0 1 a 1
1 2 b 2
2 3 c 3
3 1 a 1
我有来自两个来源的相同数据。两者都在 pandas DataFrame
秒。一些事情正在发生:
- 由于某些旧软件的读取错误,来自
source 1
(左)的数据只是来自source 2
(右)的数据的一个子集。 - 来自
source 2
的数据多了一列。 - 两个数据源都可能包含有效的重复值。
- 两者之间没有共享唯一键。
期望的结果
- 我想合并两者,保持交集。
- 仅当两个数据框中都存在重复项时才应保留重复项。这似乎很难,因为两个数据帧的长度不同并且没有共享唯一键。
- 第二个数据框中的额外列应该在新的合并数据框中。
工作示例/我尝试过的
这是一个简单的例子:
df1 = pd.DataFrame(
{ # last entry a duplicate of the first
'var1' : [1, 2, 3, 1,],
'var2' : ['a', 'b', 'c', 'a']
}
)
df2 = pd.DataFrame(
{ # last two entries duplicates of first two.
'cat': [1, 2, 3, 4, 1, 2],
'var1' : [1, 2, 3, 4, 1, 2],
'var2' : ['a', 'b', 'c', 'd', 'a', 'b']
}
)
merged = pd.merge(df1, df2, on=["var1", "var2"], how="inner")
merged
结果:
# - indicates undesired duplicates
var1 var2 cat
0 1 a 1
1 1 a 1
2 1 a 1 #
3 1 a 1 #
4 2 b 2
5 2 b 2 #
6 3 c 3
但我期待的是(顺序无关紧要):
var1 var2 cat
0 1 a 1
1 1 a 1
2 2 b 2
3 3 c 3
我查看了删除重复项,但它不会歧视并破坏有价值的信息。
merged.drop_duplicates()
var1 var2 cat
0 1 a 1
4 2 b 2
6 3 c 3
我的一个想法是想出一种方法,让两个以上的二进制列在合并之前标识源,并删除两个列都不正确的任何行。
var1 var2 cat src1 src2
0 1 a 1 1 1
1 1 a 1 1 1
2 1 a 1 0 1 # drop
3 1 a 1 0 1 # drop
4 2 b 2 1 1
5 2 b 2 0 1 # drop
6 3 c 3 1 1
但是,我不确定如何在合并期间实现这种标记(如果可能的话)。
问题:
所以,简而言之,问题是 “如何合并两个表,仅当它们存在于两个表中时才允许保留重复项”?
尝试与枚举合并:
key_cols = ['var1','var2']
(df1.assign(enum=df1.groupby(key_cols).cumcount())
.merge(df2.assign(enum=df2.groupby(key_cols).cumcount()),
on=['enum'] + key_cols, how='inner')
.drop('enum', axis=1)
)
输出:
var1 var2 cat
0 1 a 1
1 2 b 2
2 3 c 3
3 1 a 1