如何从pandas python中另一个数据帧的子集交集中减去一个数据帧?

时间:2017-11-03 22:19:13

标签: python pandas dataframe subtraction

我在python中有以下数据帧:

dataframe 1

             1  2  3  4  5
dog   dog    0  1  1  0  1
      fox    1  0  0  0  0
      jumps  0  0  0  1  0
      over   1  0  1  0  1
      the    0  1  0  0  0
fox   dog    0  0  1  1  1
      fox    0  0  0  0  0
      jumps  0  0  1  0  1
      over   0  1  0  0  0
      the    0  0  0  1  1
jumps dog    0  0  0  0  0
      fox    0  1  0  1  1
      jumps  0  0  0  0  1
      over   1  0  1  0  0
      the    0  0  0  0  0
over  dog    0  0  1  0  0
      fox    0  1  0  1  1
      jumps  0  0  0  0  0
      over   0  1  0  1  0
      the    1  0  1  0  0
the   dog    0  0  1  0  0
      fox    0  0  0  0  1
      jumps  0  1  0  0  0
      over   0  0  1  1  0
      the    0  1  1  0  1

dataframe 2

             1  2  4  5
dog   dog    1  0  0  0
      fox    0  1  0  1
      jumps  0  1  1  0
      the    0  0  0  0
      horse  1  0  1  0
fox   dog    0  0  0  0
      fox    0  1  0  1
      over   0  0  0  0
      the    0  1  0  1
      cat    0  0  1  0

您可以看到dataframe2包含dataframe1的多索引,但它还包含其他多索引,如马和猫。数据帧2也不包含数据帧1的所有列,因为您可以看到它错过了第3列。

我想从数据帧1中减去数据帧2,使得该函数仅减去两者中常见的数据并忽略其余数据,结果数据帧的形状为数据帧2。

有没有人知道pandas是否提供了内置的方法,或者我是否需要自己构建一个函数。如果是这样,你能指出我正确的方向吗?任何建议都非常感谢。谢谢。

注意:此问题类似于我发布here的另一个问题,除了我不想比较这些问题,而是想要进行减法的算术运算。< / p>

4 个答案:

答案 0 :(得分:4)

IIUC:

In [24]: r = d1.sub(d2, axis=0)

In [25]: r.loc[r.index.intersection(d2.index)]
Out[25]:
             1    2   3    4    5
dog dog   -1.0  1.0 NaN  0.0  1.0
    fox    1.0 -1.0 NaN  0.0 -1.0
    horse  NaN  NaN NaN  NaN  NaN
    jumps  0.0 -1.0 NaN  0.0  0.0
    the    0.0  1.0 NaN  0.0  0.0
fox cat    NaN  NaN NaN  NaN  NaN
    dog    0.0  0.0 NaN  1.0  1.0
    fox    0.0 -1.0 NaN  0.0 -1.0
    over   0.0  1.0 NaN  0.0  0.0
    the    0.0 -1.0 NaN  1.0  0.0

答案 1 :(得分:4)

我相信你只想要这样的东西:

In [23]: (df2 - df1.drop('3', axis=1)).fillna(df2).dropna()
Out[23]:
             1    2    4    5
dog dog    1.0 -1.0  0.0 -1.0
    fox   -1.0  1.0  0.0  1.0
    horse  1.0  0.0  1.0  0.0
    jumps  0.0  1.0  0.0  0.0
    the    0.0 -1.0  0.0  0.0
fox cat    0.0  0.0  1.0  0.0
    dog    0.0  0.0 -1.0 -1.0
    fox    0.0  1.0  0.0  1.0
    over   0.0 -1.0  0.0  0.0
    the    0.0  1.0 -1.0  0.0

Pandas已经自动对齐索引,这是它的神奇之处,但你只需要智能地填充/删除nans。

修改

哎呀,你实际上想要df1 - df2,但是df2的形状,从那以后fillna(df1)稍微有点棘手,会阻止我们放弃正确的行,但是,你可以只需使用乘以-1!

In [25]: (df2 - df1.drop('3', axis=1)).fillna(df2).dropna() * -1
Out[25]:
             1    2    4    5
dog dog   -1.0  1.0 -0.0  1.0
    fox    1.0 -1.0 -0.0 -1.0
    horse -1.0 -0.0 -1.0 -0.0
    jumps -0.0 -1.0 -0.0 -0.0
    the   -0.0  1.0 -0.0 -0.0
fox cat   -0.0 -0.0 -1.0 -0.0
    dog   -0.0 -0.0  1.0  1.0
    fox   -0.0 -1.0 -0.0 -1.0
    over  -0.0  1.0 -0.0 -0.0
    the   -0.0 -1.0  1.0 -0.0

或者,如果那些负面零点打扰你:

In [31]: (-df2 + df1.drop('3', axis=1)).fillna(-df2).dropna()
Out[31]:
             1    2    4    5
dog dog   -1.0  1.0  0.0  1.0
    fox    1.0 -1.0  0.0 -1.0
    horse -1.0  0.0 -1.0  0.0
    jumps  0.0 -1.0  0.0  0.0
    the    0.0  1.0  0.0  0.0
fox cat    0.0  0.0 -1.0  0.0
    dog    0.0  0.0  1.0  1.0
    fox    0.0 -1.0  0.0 -1.0
    over   0.0  1.0  0.0  0.0
    the    0.0 -1.0  1.0  0.0

答案 2 :(得分:3)

让我们做一些像

这样的事情
id=df2.index.values.tolist()
dd=df1.loc[list(set(df1.index.values.tolist())&set(id))]
(df2-dd).combine_first(df2).dropna(1)

             1    2    4    5
dog dog    1.0 -1.0  0.0 -1.0
    fox   -1.0  1.0  0.0  1.0
    horse  1.0  0.0  1.0  0.0
    jumps  0.0  1.0  0.0  0.0
    the    0.0 -1.0  0.0  0.0
fox cat    0.0  0.0  1.0  0.0
    dog    0.0  0.0 -1.0 -1.0
    fox    0.0  1.0  0.0  1.0
    over   0.0 -1.0  0.0  0.0
    the    0.0  1.0 -1.0  0.0

答案 3 :(得分:2)

pd.DataFrame.align与参数'inner'一起使用可将两个数据帧仅减少为公共索引。然后将结果传递给pd.DataFrame.sub

pd.DataFrame.sub(*df1.align(df2, 'inner'))

           1  2  4  5
dog dog   -1  1  0  1
    fox    1 -1  0 -1
    jumps  0 -1  0  0
    the    0  1  0  0
fox dog    0  0  1  1
    fox    0 -1  0 -1
    over   0  1  0  0
    the    0 -1  1  0

写成两行

a, b = df1.align(df2, 'inner')
a - b
相关问题