在多索引数据帧中添加和重命名列

2024-06-09 09:47:19 发布

您现在位置:Python中文网/ 问答频道 /正文

本文的目的是了解如何使用apply()shift()将列添加到MultiIndex.DataFrame中的级别

创建数据帧

import pandas as pd

df = pd.DataFrame(
[
    [5777, 100, 5385, 200, 5419, 4887, 100, 200],
    [4849, 0, 4539, 0, 3381, 0, 0, ],
    [4971, 0, 3824, 0, 4645, 3424, 0, 0, ],
    [4827, 200, 3459, 300, 4552, 3153, 100, 200, ],
    [5207, 0, 3670, 0, 4876, 3358, 0, 0, ],
],
index=pd.to_datetime(['2010-01-01',
                      '2010-01-02',
                      '2010-01-03',
                      '2010-01-04',
                      '2010-01-05']),
columns=pd.MultiIndex.from_tuples(
    [('Portfolio A', 'GBP', 'amount'), ('Portfolio A', 'GBP', 'injection'),
     ('Portfolio B', 'EUR', 'amount'), ('Portfolio B', 'EUR', 'injection'),
     ('Portfolio A', 'USD', 'amount'), ('Portfolio A', 'USD', 'injection'),
     ('Portfolio B', 'JPY', 'amount'), ('Portfolio B', 'JPY', 'injection')])
).sortlevel(axis=1)

print df

我想使用以下方法在级别2的每个货币中添加一个名为daily_added_value的新列:

^{pr2}$

但是这会抛出一个键错误:KeyError: 'amount'

方法calc_daily_added_value()的正确语法是什么?在


根据下面的答案,仍然存在一个问题

增加日还款额

dav = df.loc[:, pd.IndexSlice[:, :, 'daily_added_value']]
amount = df.loc[:, pd.IndexSlice[:, :, 'amount']]
dr = (dav.values / amount.shift()) * 100
dr.columns.set_levels(['daily_return'], level=2, inplace=True)
df = pd.concat([df, dr], axis=1).sortlevel(axis=1)

将累计复合收益相加失败

dr = df.loc[:, pd.IndexSlice[:, :, 'daily_return']]
drc = 100*((1+dr / 100).cumprod()-1)
drc.columns.set_levels(['daily_return_cumulative'], level=2, inplace=True)
df = pd.concat([df, drc], axis=1).sort_index(axis=1)
df.head()

这失败了,因为它缺少.值,但是如果我添加它,它会变成一个数组?在

但奇怪的是,drc实际上是一个形状正确的数据帧,并且似乎包含正确的结果。在

这一行失败:

drc.columns.set_levels(['daily_return_cumulative'], level=2, inplace=True)

错误是ValueError: On level 2, label max (2) >= length of level (1). NOTE: this index is in an inconsistent state

如何将索引恢复到一致状态?


Tags: columnsdfaddedindexreturnvaluelevelamount
1条回答
网友
1楼 · 发布于 2024-06-09 09:47:19

跳过groupby这是不必要的

amount = df.loc[:, pd.IndexSlice[:, :, 'amount']]
inject = df.loc[:, pd.IndexSlice[:, :, 'injection']]
dav = amount - amount.shift() - inject.shift().values
#dav.columns.set_levels(['daily_added_value'], level=2, inplace=True)

pd.concat([df, dav], axis=1).sort_index(axis=1).T

注意:我使用T来获得一张很容易符合

的图片

enter image description here

set_levels中似乎有一个bug,因此不建议使用它。在

在DataFrame dav中重命名MultiIndex列的解决方法

^{pr2}$

相关问题 更多 >