首页 > 解决方案 > 读取 Excel 文件时将 pandas MultiIndex 协调为字符串

问题描述

我正在使用read_excel(). 不幸的是,似乎很难确保 Excel 中单元格的格式,因此碰巧有这样的表格:

       2018                2019
          a         b         a         b
0  1.295666 -0.544973  0.845973 -0.874668
1  0.590123  0.284364 -1.482706 -0.859350
2  0.832228  0.469992  0.994865  0.480301
3  0.098671  0.198643  0.878323 -0.119761

...实际上有令人惊讶的索引或列:

df.columns

MultiIndex(levels=[[2018, 2019, '2019'], ['a', 'b']],
           labels=[[0, 0, 1, 2], [0, 1, 0, 1]])

如您所见,最后一列的主索引实际上有一个 2019 的字符串,而不是其他整数。

为了安全起见,我想将所有索引转换为string,但熊猫不会让我:

df.columns.set_levels(df.columns.levels[0].astype(str), level=0)

ValueError: Level values must be unique: ['2018', '2019', '2019'] on level 0

我看到两种方法来解决这个问题:

  1. 已将read_excel()列标题转换为字符串或
  2. set_levels()我上面的例子一样工作。

但我无法工作 - 有什么提示吗?

标签: pythonpandasmulti-index

解决方案


index您可以为列重新创建多个

idx=pd.MultiIndex.from_product([df.columns.levels[0].astype(int).unique(),df.columns.levels[1]])
df.columns=idx
df.columns
MultiIndex(levels=[[2018, 2019], ['a', 'b']],
           labels=[[0, 0, 1, 1], [0, 1, 0, 1]])

从 op 更好的布局格式

df.columns = pd.MultiIndex.from_product([c.astype(str).unique() for c in df.columns.levels])

更新/警告

此解决方案可能会导致一些头痛。data.columns.codes(正式称为data.columns.labels)不一定从 开始以递增的顺序出现read_excel(),例如FrozenList([[3, 3, 2, 2, 1, 1, 0, 0], [1, 0, 1, 0, 1, 0, 1, 0]])可以出现。在此处使用该.from_product()方法时,这会引起麻烦并更改列名的顺序...一种解决方法是保存其状态并在契约后将其写回:

old_col_codes = df.columns.codes
df.columns = pd.MultiIndex.from_product([c.astype(str).unique() for c in df.columns.levels])
df.columns.set_codes(old_df_codes, inplace=True)

推荐阅读