我有两个数据帧df1和df2,其中df2是df1的子集。我如何得到一个新的数据帧(df3),这是两个数据帧之间的差异?

换句话说,一个在df1中所有的行/列都不在df2中的数据帧?


当前回答

正如这里提到的 那

df1[~df1.apply(tuple,1).isin(df2.apply(tuple,1))]

是正确的解决方案,但它会产生错误的输出如果

df1=pd.DataFrame({'A':[1],'B':[2]})
df2=pd.DataFrame({'A':[1,2,3,3],'B':[2,3,4,4]})

在这种情况下,上面的溶液会给出 空数据帧,相反,你应该使用concat方法后,从每个数据帧删除重复。

使用concate和drop_duplicate

df1=df1.drop_duplicates(keep="first") 
df2=df2.drop_duplicates(keep="first") 
pd.concat([df1,df2]).drop_duplicates(keep=False)

其他回答

通过索引查找差异。假设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()

Pandas现在提供了一个新的API来处理数据帧差异:Pandas . datafframe .compare

df.compare(df2)
  col1       col3
  self other self other
0    a     c  NaN   NaN
2  NaN   NaN  3.0   4.0

试试这个: Df_new = df1。merge(df2, how='outer', indicator=True)。查询('_merge == "left_only"')。下降(_merge, 1)

它将产生一个新的数据框架,其差异是:df1中存在的值,而df2中不存在。

也许是一个简单的单行程序,具有相同或不同的列名。即使df2['Name2']包含重复的值也能正常工作。

newDf = df1.set_index('Name1')
           .drop(df2['Name2'], errors='ignore')
           .reset_index(drop=False)