如果在另一个数据框中找到重复项,如何从一个数据框中删除重复项
How to drop duplicates from one data frame if found in another dataframe
我有两个数据框,每个都有数百列。
#df1 = 190 columns
#df2 = 262 columns
#subset dataframe
df1 = pd.DataFrame({'Key': ['10003', '10009', '10010', '10034', '10665'],
'Num1': [12,13,13,13,13],
'Color': ['red','orange','red','red','red'],
'Date1': [20120506, 20120506, 20120506,20120506,20120620],
'Date2': [20120528, 20120507, 20120615,20120629,20120621]})
df2 = pd.DataFrame({'Key': ['10003', '10009', '10010', '10011', '10012','10034','10034', '10034'],
'Num1': [12,13,13,13,13,13,14,14],
'Num2': [121,122,122,124,125,126,127,128],
'Date1': [20120506, 20120506, 20120506,20120506,20120620,20120506,20120206,20120405],
'Date2': [20120528, 20120507, 20120615,20120629,20120621,20120629,20120506,20120506]})
我想删除 df2 中也存在于 df1 中的所有行,但保持 df1 不变。
我在使用 pd.concat() 或 merge() 时非常接近,但问题是我正在创建一堆不必要的列 [使用 concat() 和 merge()] 并且只找到行在 df1 中添加到 df2 [with concat()]。实际上,当 'Key'、'Date1'、'Num'、'和 'Date2' 在行中很常见时,可以将它们视为重复项。
下面的尝试很接近,但它添加了来自 df1 的额外列并保留了来自 df1 的所有额外行。我不想要 df1 中的任何其他列或行,只是为了删除 df2 中存在于两个 df 中的任何重复项。 df1 将保持不变。
a = pd.concat([df2,df1])
a.drop_duplicates(subset=['Key', 'Num1','Date1','Date2'],keep=False, inplace=True)
Color Date1 Date2 Key Num1 Num2
3 NaN 20120506 20120629 10011 13 124.0
4 NaN 20120620 20120621 10012 13 125.0
6 NaN 20120206 20120506 10034 14 127.0
7 NaN 20120405 20120506 10034 14 128.0
4 red 20120620 20120621 10665 13 NaN
我也根据 的建议尝试了合并,但我仍然得到重复的列。
df_all = df2.merge(df1.drop_duplicates(), on=['Key', 'Num1','Date1','Date2'],
how='left', indicator=True)
df_all[df_all['_merge'] == 'left_only']
合并结果,
Date1 Date2 Key Num1 Num2 Color _merge
3 20120506 20120629 10011 13 124 NaN left_only
4 20120620 20120621 10012 13 125 NaN left_only
6 20120206 20120506 10034 14 127 NaN left_only
7 20120405 20120506 10034 14 128 NaN left_only
合并为我提供了正确的行,但增加了列。通常这不会是一个问题,我可以只是 .drop() 但合并后有 100 多个额外的列。
如何在不增加列或从 df1 添加额外行的情况下删除重复项。
最终预期结果:
Date1 Date2 Key Num1 Num2
3 20120506 20120629 10011 13 124.0
4 20120620 20120621 10012 13 125.0
6 20120206 20120506 10034 14 127.0
7 20120405 20120506 10034 14 128.0
使用 on
键作为 df1
的子集
In [514]: on = ['Date1', 'Date2', 'Num1', 'Key']
In [515]: (df2.merge(df1[on], on=on, how='left', indicator=True)
.query('_merge == "left_only"').drop('_merge', 1))
Out[515]:
Date1 Date2 Key Num1 Num2
3 20120506 20120629 10011 13 124
4 20120620 20120621 10012 13 125
6 20120206 20120506 10034 14 127
7 20120405 20120506 10034 14 128
您可以将 concat
与 keys
一起使用
s=pd.concat([df1,df2],keys=[1,2]).drop_duplicates(['Key', 'Num1','Date1','Date2'],keep='first')
df1=s.loc[1].dropna(axis=1)
df1
Out[1260]:
Color Date1 Date2 Key Num1
0 red 20120506 20120528 10003 12
1 orange 20120506 20120507 10009 13
2 red 20120506 20120615 10010 13
3 red 20120506 20120629 10034 13
4 red 20120620 20120621 10665 13
df2=s.loc[2].dropna(axis=1)
df2
Out[1262]:
Date1 Date2 Key Num1 Num2
3 20120506 20120629 10011 13 124.0
4 20120620 20120621 10012 13 125.0
6 20120206 20120506 10034 14 127.0
7 20120405 20120506 10034 14 128.0
这是一种方式。只需在相反方向连接,然后删除重复项。最后从 df1
.
中删除不需要的 rows/columns
df = pd.concat([df1, df2], ignore_index=True)\
.drop_duplicates(subset=['Date1', 'Date2', 'Key', 'Num1'], keep=False)
df = df.drop(df1.index & df.index, 0)\
.drop(set(df1.columns) - set(df2.columns), 1)
# Date1 Date2 Key Num1 Num2
# 8 20120506 20120629 10011 13 124.0
# 9 20120620 20120621 10012 13 125.0
# 11 20120206 20120506 10034 14 127.0
# 12 20120405 20120506 10034 14 128.0
这与 非常相似,主要区别在于删除不需要的 df1
数据是明确的。但是请注意,此方法会重置索引。
我有两个数据框,每个都有数百列。
#df1 = 190 columns
#df2 = 262 columns
#subset dataframe
df1 = pd.DataFrame({'Key': ['10003', '10009', '10010', '10034', '10665'],
'Num1': [12,13,13,13,13],
'Color': ['red','orange','red','red','red'],
'Date1': [20120506, 20120506, 20120506,20120506,20120620],
'Date2': [20120528, 20120507, 20120615,20120629,20120621]})
df2 = pd.DataFrame({'Key': ['10003', '10009', '10010', '10011', '10012','10034','10034', '10034'],
'Num1': [12,13,13,13,13,13,14,14],
'Num2': [121,122,122,124,125,126,127,128],
'Date1': [20120506, 20120506, 20120506,20120506,20120620,20120506,20120206,20120405],
'Date2': [20120528, 20120507, 20120615,20120629,20120621,20120629,20120506,20120506]})
我想删除 df2 中也存在于 df1 中的所有行,但保持 df1 不变。
我在使用 pd.concat() 或 merge() 时非常接近,但问题是我正在创建一堆不必要的列 [使用 concat() 和 merge()] 并且只找到行在 df1 中添加到 df2 [with concat()]。实际上,当 'Key'、'Date1'、'Num'、'和 'Date2' 在行中很常见时,可以将它们视为重复项。
下面的尝试很接近,但它添加了来自 df1 的额外列并保留了来自 df1 的所有额外行。我不想要 df1 中的任何其他列或行,只是为了删除 df2 中存在于两个 df 中的任何重复项。 df1 将保持不变。
a = pd.concat([df2,df1])
a.drop_duplicates(subset=['Key', 'Num1','Date1','Date2'],keep=False, inplace=True)
Color Date1 Date2 Key Num1 Num2
3 NaN 20120506 20120629 10011 13 124.0
4 NaN 20120620 20120621 10012 13 125.0
6 NaN 20120206 20120506 10034 14 127.0
7 NaN 20120405 20120506 10034 14 128.0
4 red 20120620 20120621 10665 13 NaN
我也根据
df_all = df2.merge(df1.drop_duplicates(), on=['Key', 'Num1','Date1','Date2'],
how='left', indicator=True)
df_all[df_all['_merge'] == 'left_only']
合并结果,
Date1 Date2 Key Num1 Num2 Color _merge
3 20120506 20120629 10011 13 124 NaN left_only
4 20120620 20120621 10012 13 125 NaN left_only
6 20120206 20120506 10034 14 127 NaN left_only
7 20120405 20120506 10034 14 128 NaN left_only
合并为我提供了正确的行,但增加了列。通常这不会是一个问题,我可以只是 .drop() 但合并后有 100 多个额外的列。
如何在不增加列或从 df1 添加额外行的情况下删除重复项。
最终预期结果:
Date1 Date2 Key Num1 Num2
3 20120506 20120629 10011 13 124.0
4 20120620 20120621 10012 13 125.0
6 20120206 20120506 10034 14 127.0
7 20120405 20120506 10034 14 128.0
使用 on
键作为 df1
In [514]: on = ['Date1', 'Date2', 'Num1', 'Key']
In [515]: (df2.merge(df1[on], on=on, how='left', indicator=True)
.query('_merge == "left_only"').drop('_merge', 1))
Out[515]:
Date1 Date2 Key Num1 Num2
3 20120506 20120629 10011 13 124
4 20120620 20120621 10012 13 125
6 20120206 20120506 10034 14 127
7 20120405 20120506 10034 14 128
您可以将 concat
与 keys
s=pd.concat([df1,df2],keys=[1,2]).drop_duplicates(['Key', 'Num1','Date1','Date2'],keep='first')
df1=s.loc[1].dropna(axis=1)
df1
Out[1260]:
Color Date1 Date2 Key Num1
0 red 20120506 20120528 10003 12
1 orange 20120506 20120507 10009 13
2 red 20120506 20120615 10010 13
3 red 20120506 20120629 10034 13
4 red 20120620 20120621 10665 13
df2=s.loc[2].dropna(axis=1)
df2
Out[1262]:
Date1 Date2 Key Num1 Num2
3 20120506 20120629 10011 13 124.0
4 20120620 20120621 10012 13 125.0
6 20120206 20120506 10034 14 127.0
7 20120405 20120506 10034 14 128.0
这是一种方式。只需在相反方向连接,然后删除重复项。最后从 df1
.
df = pd.concat([df1, df2], ignore_index=True)\
.drop_duplicates(subset=['Date1', 'Date2', 'Key', 'Num1'], keep=False)
df = df.drop(df1.index & df.index, 0)\
.drop(set(df1.columns) - set(df2.columns), 1)
# Date1 Date2 Key Num1 Num2
# 8 20120506 20120629 10011 13 124.0
# 9 20120620 20120621 10012 13 125.0
# 11 20120206 20120506 10034 14 127.0
# 12 20120405 20120506 10034 14 128.0
这与 df1
数据是明确的。但是请注意,此方法会重置索引。