Pandas Column Multiindex相互减去列

时间:2017-08-18 18:37:00

标签: python pandas multi-index

pandas DataFrame:

构造

c = pd.MultiIndex.from_product([['AAPL','AMZN'],['price','custom']])
i = pd.date_range(start='2017-01-01',end='2017-01-6')
df1 = pd.DataFrame(index=i,columns=c)

df1.loc[:,('AAPL','price')] = list(range(51,57))
df1.loc[:,('AMZN','price')] = list(range(101,107))
df1.loc[:,('AAPL','custom')] = list(range(1,7))
df1.loc[:,('AMZN','custom')] = list(range(17,23))
df1.index.set_names('Dates',inplace=True)
df1.sort_index(axis=1,level=0,inplace=True) # needed for pd.IndexSlice[]

df1

产生:(无法弄清楚如何格式化Jupyter Notebook的输出)

    AAPL    AMZN
    custom  price   custom  price
Dates               
2017-01-01  1   51  17  101
2017-01-02  2   52  18  102
2017-01-03  3   53  19  103
2017-01-04  4   54  20  104
2017-01-05  5   55  21  105
2017-01-06  6   56  22  106

问题: 如何在MultiIndex的第二级创建第3列,即pricecustom之间的差异?这应该针对每个顶级列单独计算,即分别针对AAPL和AMZN计算。

尝试解决方案:

我尝试以两种方式使用pd.IndexSlice,两者都给了我所有NaNs

df1.loc[:,pd.IndexSlice[:,'price']].sub(df1.loc[:,pd.IndexSlice[:,'custom']])
df1.loc[:,pd.IndexSlice[:,'price']] - df1.loc[:,pd.IndexSlice[:,'custom']]

返回:

    AAPL    AMZN
    custom  price   custom  price
Dates               
2017-01-01  NaN NaN NaN NaN
2017-01-02  NaN NaN NaN NaN
2017-01-03  NaN NaN NaN NaN
2017-01-04  NaN NaN NaN NaN
2017-01-05  NaN NaN NaN NaN
2017-01-06  NaN NaN NaN NaN

如何添加带有差异的第三列?

感谢。

2 个答案:

答案 0 :(得分:3)

您可以按值减去,然后重命名并最后加入原始:

a = df1.loc[:,pd.IndexSlice[:,'price']].sub(df1.loc[:,pd.IndexSlice[:,'custom']].values, 1)
       .rename(columns={'price':'sub'})
df1 = df1.join(a).sort_index(axis=1)
print (df1)
             AAPL             AMZN          
           custom price sub custom price sub
Dates                                       
2017-01-01      1    51  50     17   101  84
2017-01-02      2    52  50     18   102  84
2017-01-03      3    53  50     19   103  84
2017-01-04      4    54  50     20   104  84
2017-01-05      5    55  50     21   105  84
2017-01-06      6    56  50     22   106  84

答案 1 :(得分:2)

您可以考虑减去值:

df1.loc[:, pd.IndexSlice[:, 'price']] - df1.loc[:,pd.IndexSlice[:,'custom']].values

要将其加入,您可以使用pd.concat

In [221]: df2 = (df1.loc[:, pd.IndexSlice[:, 'price']] - df1.loc[:,pd.IndexSlice[:,'custom']].values)\
                            .rename(columns={'price' : 'new'})

In [222]: pd.concat([df1, df2], axis=1)
Out[222]: 
             AAPL         AMZN       AAPL AMZN
           custom price custom price  new  new
Dates                                         
2017-01-01      1    51     17   101   50   84
2017-01-02      2    52     18   102   50   84
2017-01-03      3    53     19   103   50   84
2017-01-04      4    54     20   104   50   84
2017-01-05      5    55     21   105   50   84
2017-01-06      6    56     22   106   50   84