熊猫列多索引相互减去列

Jos*_*h D 6 python multi-index pandas

熊猫数据框:

构造函数:

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
Run Code Online (Sandbox Code Playgroud)

产生:(不知道如何格式化 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
Run Code Online (Sandbox Code Playgroud)

问: 我怎样才能在多指标的第二个级别的区别是创建一个第三列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']]
Run Code Online (Sandbox Code Playgroud)

返回:

    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
Run Code Online (Sandbox Code Playgroud)

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

谢谢。

cs9*_*s95 7

您可以考虑减去这些值:

df1.loc[:, pd.IndexSlice[:, 'price']] - df1.loc[:,pd.IndexSlice[:,'custom']].values
Run Code Online (Sandbox Code Playgroud)

要加入它,您可以使用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
Run Code Online (Sandbox Code Playgroud)