我在python中有以下数据帧:
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
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>
答案 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