我有两个数据帧df1和df2,其中df2是df1的子集。我如何得到一个新的数据帧(df3),这是两个数据帧之间的差异?
换句话说,一个在df1中所有的行/列都不在df2中的数据帧?
我有两个数据帧df1和df2,其中df2是df1的子集。我如何得到一个新的数据帧(df3),这是两个数据帧之间的差异?
换句话说,一个在df1中所有的行/列都不在df2中的数据帧?
当前回答
通过索引查找差异。假设df1是df2的一个子集,并且在进行子集设置时将索引前移
df1.loc[set(df1.index).symmetric_difference(set(df2.index))].dropna()
# Example
df1 = pd.DataFrame({"gender":np.random.choice(['m','f'],size=5), "subject":np.random.choice(["bio","phy","chem"],size=5)}, index = [1,2,3,4,5])
df2 = df1.loc[[1,3,5]]
df1
gender subject
1 f bio
2 m chem
3 f phy
4 m bio
5 f bio
df2
gender subject
1 f bio
3 f phy
5 f bio
df3 = df1.loc[set(df1.index).symmetric_difference(set(df2.index))].dropna()
df3
gender subject
2 m chem
4 m bio
其他回答
定义数据框架:
df1 = pd.DataFrame({
'Name':
['John','Mike','Smith','Wale','Marry','Tom','Menda','Bolt','Yuswa'],
'Age':
[23,45,12,34,27,44,28,39,40]
})
df2 = df1[df1.Name.isin(['John','Smith','Wale','Tom','Menda','Yuswa'])
df1
Name Age
0 John 23
1 Mike 45
2 Smith 12
3 Wale 34
4 Marry 27
5 Tom 44
6 Menda 28
7 Bolt 39
8 Yuswa 40
df2
Name Age
0 John 23
2 Smith 12
3 Wale 34
5 Tom 44
6 Menda 28
8 Yuswa 40
两者之间的区别是:
df1[~df1.isin(df2)].dropna()
Name Age
1 Mike 45.0
4 Marry 27.0
7 Bolt 39.0
地点:
isin(df2)返回df1中也在df2中的行。 ~(元素逻辑NOT)在表达式前面对结果求反,因此我们得到df1中不在df2中的元素——两者之间的差值。 .dropna()删除NaN显示所需输出的行
注意:这只适用于len(df1) >= len(df2)。如果df2比df1长,可以反转表达式:df2[~df2.isin(df1)].dropna()
对称差分
如果你只对其中一个数据帧中的行感兴趣,而不是两个数据帧中的行,你在寻找集的差异:
pd.concat([df1,df2]).drop_duplicates(keep=False)
⚠️只有在两个数据帧都不包含任何重复的情况下才有效。
设置差分/关系代数差分
如果你对关系代数差异/集差异感兴趣,即df1-df2或df1\df2:
pd.concat([df1,df2,df2]).drop_duplicates(keep=False)
⚠️只有在两个数据帧都不包含任何重复的情况下才有效。
也许是一个简单的单行程序,具有相同或不同的列名。即使df2['Name2']包含重复的值也能正常工作。
newDf = df1.set_index('Name1')
.drop(df2['Name2'], errors='ignore')
.reset_index(drop=False)
对于行,尝试这样做,其中Name是联合索引列(可以是多个公共列的列表,或者指定left_on和right_on):
m = df1.merge(df2, on='Name', how='outer', suffixes=['', '_'], indicator=True)
indicator=True设置很有用,因为它添加了一个名为_merge的列,其中包含df1和df2之间的所有更改,分为3种可能的类型:“left_only”,“right_only”或“both”。
对于列,试试这个:
set(df1.columns).symmetric_difference(df2.columns)
import pandas as pd
# given
df1 = pd.DataFrame({'Name':['John','Mike','Smith','Wale','Marry','Tom','Menda','Bolt','Yuswa',],
'Age':[23,45,12,34,27,44,28,39,40]})
df2 = pd.DataFrame({'Name':['John','Smith','Wale','Tom','Menda','Yuswa',],
'Age':[23,12,34,44,28,40]})
# find elements in df1 that are not in df2
df_1notin2 = df1[~(df1['Name'].isin(df2['Name']) & df1['Age'].isin(df2['Age']))].reset_index(drop=True)
# output:
print('df1\n', df1)
print('df2\n', df2)
print('df_1notin2\n', df_1notin2)
# df1
# Age Name
# 0 23 John
# 1 45 Mike
# 2 12 Smith
# 3 34 Wale
# 4 27 Marry
# 5 44 Tom
# 6 28 Menda
# 7 39 Bolt
# 8 40 Yuswa
# df2
# Age Name
# 0 23 John
# 1 12 Smith
# 2 34 Wale
# 3 44 Tom
# 4 28 Menda
# 5 40 Yuswa
# df_1notin2
# Age Name
# 0 45 Mike
# 1 27 Marry
# 2 39 Bolt