简体   繁体   English

重命名多索引/多级Pandas DataFrame中的级别

[英]Rename level in multiindex/multilevel Pandas DataFrame

I have a DataFrame like this: 我有一个像这样的DataFrame

arrays = [np.array(['bar', 'bar', 'baz', 'baz', 'foo', 'foo', 'qux', 'qux']),
          np.array(['one', 'two', 'one', 'two', 'one', 'two', 'one', 'two']),
          np.array(['2016-01', '2016-02', '2016-01', '2016-02', '2016-01', '2016-02', '2016-01', '2016-02'])]
df = pd.DataFrame(np.ceil(np.random.randn(8, 4)), index=arrays)

df.rename(columns={0:'m1',1:'m2',2:'m3',3:'m4'},inplace=True)

                  m1   m2   m3   m4
bar one 2016-01 -0.0  1.0  3.0  2.0
    two 2016-02  1.0  1.0  1.0  2.0
baz one 2016-01 -1.0 -1.0  2.0  1.0
    two 2016-02  1.0  2.0  1.0  2.0
foo one 2016-01  1.0 -0.0 -0.0 -0.0
    two 2016-02 -2.0 -0.0 -0.0 -0.0
qux one 2016-01 -0.0 -0.0 -1.0  1.0
    two 2016-02 -0.0 -0.0  1.0 -0.0

Let's say I want to replace all 2016 for 2017 in the column name for m2 and m4 so that the 2016 rows will have values for m1 and m3 but not for m2 and m4. 假设我要在m2和m4的列名称中替换2017年的所有2016年,以便2016年的行将具有m1和m3的值,但没有m2和m4的值。 And so the 2017 rows will have values for m2 and m4 but not m1 and m3. 因此,2017年的行将具有m2和m4的值,但没有m1和m3的值。 Something similar to this DataFrame : 与此DataFrame相似:

                  m1   m2   m3   m4
bar one 2016-01 -0.0  0.0  3.0  0.0
    two 2016-02  1.0  0.0  1.0  0.0
    one 2017-01  0.0  1.0  0.0  2.0
    two 2017-02  0.0  1.0  0.0  2.0
baz one 2016-01 -1.0  0.0  2.0  0.0
    two 2016-02  1.0  0.0  1.0  0.0
    one 2017-01  0.0 -1.0  0.0  1.0
    two 2017-02  0.0  2.0  0.0  2.0

I've tried to unstack() the dataframe and rename each column but that doesn't seem to work and I'm not sure why. 我试图unstack()数据框并重命名每列,但这似乎不起作用,我不确定为什么。

df = df.unstack()
df.unstack()['m2'] = df.unstack()['m2'].rename(columns = lambda t: t.replace('2016','2017'))
import numpy as np
import pandas as pd
np.random.seed(2017)

arrays = [np.array(['bar', 'bar', 'baz', 'baz', 'foo', 'foo', 'qux', 'qux']),
          np.array(['one', 'two', 'one', 'two', 'one', 'two', 'one', 'two']),
          np.array(['2016-01', '2016-02', '2016-01', '2016-02', '2016-01', '2016-02', '2016-01', '2016-02'])]
df = pd.DataFrame(np.ceil(np.random.randn(8, 4)), index=arrays)

df.rename(columns={0:'m1',1:'m2',2:'m3',3:'m4'},inplace=True)

df2 = df[['m2', 'm4']]
df2.index = pd.MultiIndex.from_arrays(
    [df.index.get_level_values(i) for i in [0,1]]
    + [df.index.get_level_values(-1).str.replace('2016','2017')])

result = pd.concat([df[['m1','m3']], df2], axis=0).fillna(0)
result = result.sort_index(level=[0,2,1])
print(result)

converts 转换

                  m1   m2   m3   m4
bar one 2016-01 -1.0 -0.0  1.0  1.0
    two 2016-02 -0.0 -0.0 -0.0 -0.0
baz one 2016-01  1.0 -0.0 -1.0 -0.0
    two 2016-02 -1.0  1.0  1.0 -0.0
foo one 2016-01 -0.0 -0.0 -1.0 -1.0
    two 2016-02  2.0 -0.0 -0.0 -0.0
qux one 2016-01  1.0  2.0 -0.0  2.0
    two 2016-02  1.0  1.0 -0.0 -0.0

into

                  m1   m2   m3   m4
bar one 2016-01 -1.0  0.0  1.0  0.0
    two 2016-02 -0.0  0.0 -0.0  0.0
    one 2017-01  0.0 -0.0  0.0  1.0
    two 2017-02  0.0 -0.0  0.0 -0.0
baz one 2016-01  1.0  0.0 -1.0  0.0
    two 2016-02 -1.0  0.0  1.0  0.0
    one 2017-01  0.0 -0.0  0.0 -0.0
    two 2017-02  0.0  1.0  0.0 -0.0
foo one 2016-01 -0.0  0.0 -1.0  0.0
    two 2016-02  2.0  0.0 -0.0  0.0
    one 2017-01  0.0 -0.0  0.0 -1.0
    two 2017-02  0.0 -0.0  0.0 -0.0
qux one 2016-01  1.0  0.0 -0.0  0.0
    two 2016-02  1.0  0.0 -0.0  0.0
    one 2017-01  0.0  2.0  0.0  2.0
    two 2017-02  0.0  1.0  0.0 -0.0

I am not sure I quite understand your question, here is what i did and the output. 我不确定我是否完全理解您的问题,这是我的工作和输出。

    arrays = [np.array(['bar', 'bar', 'baz', 'baz', 'foo', 'foo', 'qux', 'qux']),
          np.array(['one', 'two', 'one', 'two', 'one', 'two', 'one', 'two']),
          np.array(['2016-01', '2016-02', '2016-01', '2016-02', '2016-01', '2016-02', '2016-01', '2016-02'])]
df = pd.DataFrame(np.ceil(np.random.randn(8, 4)), index=arrays)

df.rename(columns={0:'m1',1:'m2',2:'m3',3:'m4'},inplace=True)
df = df.reset_index()
df['level_2'] = df['level_2'].str.replace("2016","2017")

Which gives me the output: 这给了我输出:

level_0  level_1  level_2  m1  m2  m3  m4

0   bar    one    2017-01 -0.0 -1.0 -0.0 -0.0
1   bar    two    2017-02 -0.0  -1.0 2.0  2.0
2   baz    one    2017-01  -2.0 1.0 -0.0  1.0
3   baz    two    2017-02  -0.0 1.0 -1.0  2.0
4   foo    one    2017-01  1.0  -0.0 -1.0 -0.0
5   foo    two    2017-02  -1.0 -2.0  1.0 -0.0
6   qux    one    2017-01   1.0 1.0  -0.0  1.0
7   qux    two    2017-02   1.0 -1.0  2.0 -1.0

If you could let me know what you are expecting based on this, I will modify my answer. 如果您可以根据此告诉我您的期望,我将修改我的答案。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM