从给定多个索引的 pandas 数据框中减去序列值

Subtract series value from pandas data frame given multiple index

我在 Pandas、table A 中有一个大数据框,结构如下:

key1   key2     value1 
1      201501     12      
2      201502     4     
3      201503     3      
4      201506     9      
5      201507     15
6      201509     nan 

from table A,colum value1,我想减去value2 来自 table B,外观如下,使用 key1key2 作为连接键:

key1   key2     value2 
1      201501     11      
3      201503     2
5      201507     14

我想要 table A 中的以下内容:

key1   key2     value1 
1      201501     1      
2      201502     4     
3      201503     1      
4      201506     9      
5      201507     1
6      201509     nan 

我怎样才能以超高效的方式实现这一点?今天,我将 A 中的两个 table 和 substrat value1B 中的 value2 结合在一起,我的问题是,这是否可以用更智能的 pythonic "look-up" 时尚、更时尚、更紧凑的方式来完成?

下面的数据框代码

import numpy as np

tableA= pd.DataFrame({'key1':[1,2,3,4,5,6],
                'key2':[201501,201502,201503,201506,201507,201509],
                'value1':[12,4,3,9,15,np.nan]
                })



tableB= pd.DataFrame({'key1':[1,3,5],
                'key2':[201501,201503,201507],
                'value1':[11,2,14]
                })

您可以先通过 set_index, then substract by sub and fillna 使用 MultiIndexes 创建 DataFrames DataFrame:

print (tableA.set_index(['key1','key2'])
             .sub(tableB.set_index(['key1','key2']))
             .fillna(tableA.set_index(['key1','key2']))
             .reset_index())

   key1    key2  value1
0     1  201501     1.0
1     2  201502     4.0
2     3  201503     1.0
3     4  201506     9.0
4     5  201507     1.0
5     6  201509     NaN

combine_first的另一个解决方案:

print (tableA.set_index(['key1','key2'])
             .sub(tableB.set_index(['key1','key2']))
             .combine_first(tableA.set_index(['key1','key2']))
             .reset_index())

   key1    key2  value1
0     1  201501     1.0
1     2  201502     4.0
2     3  201503     1.0
3     4  201506     9.0
4     5  201507     1.0
5     6  201509     NaN
tableA.set_index(keys).value1 \
    .sub(tableB.set_index(keys).value1, fill_value=0) \
    .reset_index()