如何重命名MultiIndex列?

时间:2019-10-29 10:49:21

标签: python pandas

如何重命名熊猫中的MultiIndex列?

例如,这是我想做的事:

function App() {
  const [carbrand, setCarBrand] = useState('');
  let cars = ["honda", "toyota", "bmw"];

  return (
    <div className="App">
      {cars.map(carName => <h1 id={carName} onClick={e => setCarBrand(e.target.id)}>{carName}</h1>)}
      {carbrand && <p>you clicked: {carbrand}</p>}
    </div>
  );
}```

I opted for doing the mapping inline for simplicity.  There's no real issue either way but stylistically, for something so simple this would be my preference.

但是,这无效,返回与原始列名称相同的DataFrame:

import pandas as pd

df = pd.DataFrame([[1, 2, 3], [4, 5, 6], [7, 8, 9]],
                  columns=pd.MultiIndex.from_tuples([('a', 1), ('a', 2), ('b', 1)]))

df.rename(columns={('a', 1): 'd', ('a', 2): 'e', ('b', 1): 'f'}, errors='raise')

我想得到:

   a     b
   1  2  1
0  1  2  3
1  4  5  6
2  7  8  9

(我使用 d e f 0 1 2 3 1 4 5 6 2 7 8 9 来确保我正确地引用了列名。)

当您没有MultiIndex时,此方法有效:

errors='raise'

返回:

df = pd.DataFrame([[1, 2, 3], [4, 5, 6], [7, 8, 9]],
                  columns=['a1', 'a2', 'b1'])

df.rename(columns={'a1': 'd', 'a2': 'e', 'b1': 'f'}, errors='raise')

我已经弄乱了各种变化,例如使用级别参数,让新名称具有相同级别的级别,但是没有运气。

还有其他相关问题,但它们往往集中于解决一些较大的问题。我可以想出解决我较大问题所需的结果的方法,但我故意不在此提出要求。这种使用 d e f 0 1 2 3 1 4 5 6 2 7 8 9 的方法似乎是最自然的方法,我想了解为什么它不起作用或我做错了什么。如果我应该使用rename的替代方法来解决我的问题,或者如果rename上的一些信息证明它没有达到我的预期,他们将不胜感激。

最相似的问题是here,但是答案没有解决我的问题:在我的示例中,指定单个级别的值是不够的,因为单个级别无法唯一地指定每个列,而rename无法处理各个列。

2 个答案:

答案 0 :(得分:0)

您可以先使用to_flat_index展平索引:

df = pd.DataFrame([[1, 2, 3], [4, 5, 6], [7, 8, 9]],
                  columns=pd.MultiIndex.from_tuples([('a', 1), ('a', 2), ('b', 1)]))

lookup = {('a', 1): 'd', ('a', 2): 'e', ('b', 1): 'f'}

# flatten index
df.columns = df.columns.to_flat_index()

# rename using lookup
result = df.rename(columns=lookup)

print(result)

输出

   d  e  f
0  1  2  3
1  4  5  6
2  7  8  9

答案 1 :(得分:0)

我建议对具有相同默认值x的{​​{3}}使用列表推导:

d = {('a', 1): 'd', ('a', 2): 'e', ('b', 1): 'f'}

df.columns = [d.get(x, x) for x in df.columns]
print (df)
   d  e  f
0  1  2  3
1  4  5  6
2  7  8  9

因为如果使用rename测试某些功能,它将分别处理每个列名:

测试

def f(x):
    print (x)

a
1
a
2
b
1

print (df.rename(columns = f))