在python中,如何从另一个数据帧的子集交集中减去一个数据帧?
我对python中的以下数据帧有一个简单的定义: 数据帧1 数据帧2 您可以看到dataframe2包含dataframe1的多索引,但它也包含额外的多索引,如horse和cat。Dataframe 2也不包含Dataframe 1的所有列,因为您可以看到它没有包含第3列 我想从dataframe 1中减去dataframe 2,这样函数就只减去两者通用的数据,而忽略其余的数据,得到的dataframe是dataframe 2的形状 有人知道pandas是否提供了一种内置的方法,或者我需要自己构造一个函数吗。如果是这样,你能给我指出正确的方向吗?非常感谢您的任何建议。多谢各位 注意:这个问题与我发布的另一个问题类似,只是我不想比较这些问题,而是想做一个减法算术运算。IIUC:在python中,如何从另一个数据帧的子集交集中减去一个数据帧?,python,pandas,dataframe,subtraction,Python,Pandas,Dataframe,Subtraction,我对python中的以下数据帧有一个简单的定义: 数据帧1 数据帧2 您可以看到dataframe2包含dataframe1的多索引,但它也包含额外的多索引,如horse和cat。Dataframe 2也不包含Dataframe 1的所有列,因为您可以看到它没有包含第3列 我想从dataframe 1中减去dataframe 2,这样函数就只减去两者通用的数据,而忽略其余的数据,得到的dataframe是dataframe 2的形状 有人知道pandas是否提供了一种内置的方法,或者我需要自己构
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
我相信你只是想要这样的东西:
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
熊猫已经在索引上自动对齐了,这是它神奇的一部分,但是你只需要智能地填充/删除NAN
编辑
哎哟,你真的想要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
让我们做一些类似的事情
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
使用
pd.DataFrame.align
和参数'internal'
将两个数据帧减少为仅通用索引。然后将结果传递给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
您能否提供一个更可行的示例,即人们实际上可以复制粘贴运行的内容?否则,很多人会转向其他问题。诚然,对于多索引来说,这可能很棘手。看这个:啊,是的,很好idea@juanpa.arrivillaga, ;-)@MaxU干得好,先生。@juanpa.arrivillaga,谢谢:)@juanpa.arrivillaga由于df2是可变的,所以没有必要将列“3”作为缺失的列。有什么想法吗?@Elisha512你可以做一些事情,比如
missing=df1.columns.difference(df2.columns)
,然后把它传递给@juanpa.arrivillaga和(-df2+df1.drop(missing,axis=1)).fillna(-df2)。dropna()正确吗?@Elisha512是的,这就是我的意思。你也有可以使用的rsub!我从来没有见过“align”方法,因为@Psidom给我展示了它。非常好。可以指定轴、填充值以及内部或外部。不确定是向左还是向右。
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