python - 如何使用设置差异比较 pandas DataFrame

标签 python python-3.x pandas dataframe set

我有 df1df2:

df1 = pd.DataFrame([[1,1,1,1],[2,2,1,1],[0,0,1,1],[1,1,1,1],[2,2,1,1],[0,0,4,1]], 
                   columns=['col1','col2','col3','col4'])
df2 = pd.DataFrame([[1,1,1,1],[3,3,1,1],[0,0,1,1],[1,1,5,1],[3,3,1,1],[0,0,1,1]], 
                   columns=['col1','col2','col3','col4'])

我删除了重复的行:

df1 = df1.drop_duplicates(subset=['col1', 'col2', 'col3'])
df2 = df2.drop_duplicates(subset=['col1', 'col2', 'col3'])

因此每个 df 都由唯一的行组成。但两个 dfs 之间存在一些重叠:

   col1  col2  col3  col4
0     1     1     1     1
1     2     2     1     1
2     0     0     1     1
5     0     0     4     1

   col1  col2  col3  col4
0     1     1     1     1
1     3     3     1     1
2     0     0     1     1
3     1     1     5     1

我的实际 df1df2 的形状约为 (5000000, 23),包括 int、float 和 object 字段。


开始编辑: 我想创建 df1_uniq (df1 中的内容但 df2 中没有的内容)和 df2_uniq (df2 中的内容但 df1 中没有的内容。

df1_iniq:
   col1  col2  col3  col4
1     2     2     1     1
5     0     0     4     1

df2_uniq:
   col1  col2  col3  col4
1     3     3     1     1
3     1     1     5     1

结束编辑


在集合表示法中,我认为这将是 df1.difference(df2)df2.difference(df1),但当我运行该代码时,我得到空集。请注意,比较每个 df 中的单个列确实有效,例如

set(df_1[field].unique()).difference(set(df_2[field].unique()))

返回[2]

另一种方法是循环遍历每个 df,如果 df1[i] 等于 df2 中的任何行,则删除两个 df 中的该行。但这是一种 O(n**2) 方法,并且需要很长时间。

有没有一种更Pythonic、pandastic的方法来做到这一点?

最佳答案

您可以将 mergeindicator=True 结合使用:

u = df1.merge(df2, how='outer', indicator=True)
df3 = u.query('_merge == "left_only"').drop('_merge', 1)
df4 = u.query('_merge == "right_only"').drop('_merge', 1)

df3

   col1  col2  col3  col4
1     2     2     1     1
3     0     0     4     1

df4

   col1  col2  col3  col4
4     3     3     1     1
5     1     1     5     1

如果 df1df2 的列名称不同,请确保它们都相同:

df1.columns = df2.columns

如果索引也需要保留,可以在合并前先重置索引,然后再设置。

u, v = df1.reset_index(), df2.reset_index()
w = (u.merge(v, how='outer', on=df1.columns.tolist(), indicator=True)
      .fillna({'index_x': -1, 'index_y': -1}, downcast='infer'))
w

   index_x  col1  col2  col3  col4  index_y      _merge
0        0     1     1     1     1        0        both
1        1     2     2     1     1       -1   left_only
2        2     0     0     1     1        2        both
3        5     0     0     4     1       -1   left_only
4       -1     3     3     1     1        1  right_only
5       -1     1     1     5     1        3  right_only

现在,

df3 = (w.query('_merge == "left_only"')
        .set_index('index_x')
        .drop(['_merge', 'index_y'], 1)
        .rename_axis([None], axis=0))
df4 = (w.query('_merge == "right_only"')
        .set_index('index_y')
        .drop(['_merge', 'index_x'], 1)
        .rename_axis([None], axis=0))

df3

   col1  col2  col3  col4
1     2     2     1     1
5     0     0     4     1

df4

   col1  col2  col3  col4
1     3     3     1     1
3     1     1     5     1

关于python - 如何使用设置差异比较 pandas DataFrame,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/54508830/

相关文章:

python - 如何用 NaN 替换 python 数据框中的破折号?

pandas - 基于 pandas 数据框中的一列进行分组

python - 动态设置tensorflow变量的可训练性

javascript - Django:返回[Object object]而不是django View 数组

Python:将索引作为新列添加到二维数组

python - 禁用日期选择器上的 Selenium 输入日期

Python,我在哪里删除字符串中元音的函数错了?

python - django 1.5 ModelForm 中的 "This field cannot be null"错误

python - 如何在 pytest hooks 中捕获打印语句

python - pandas:将数据帧减少到仅出现特定的事件链