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列,即price
和custom
之间的差异?这应该针对每个顶级列单独计算,即分别针对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
如何添加带有差异的第三列?
感谢。
答案 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