根据另一列的名称重命名Pandas多层索引

3
我有一个CSV文件,其格式我无法更改。该文件具有多级索引:两行标题。第一行(更高级别的索引)在值不变时为空白。

我的标题看起来像:

Header loos like this

实际上是这样的,而我想要的是:

What the header actually is

我希望能够使用Python 2.7和Pandas正确处理它。

我决定在索引的第一级上循环,如果值为空白,则将其设置为左侧相同的值。

我首先在Pandas中加载数据框:

df = pd.read_csv(myFile, header=[0,1], sep=',')
df

Pandas中加载的数据帧

我尝试了以下方法:

for i, val in enumerate(df.columns.values):
    if val[0][:7] == 'Unnamed':
        l.append([l[i-1][0], val[1]])
    else:
        l.append(val)

我得到的列表“l”似乎是我想要的:
[('Foo', 'A'),
 ['Foo', 'B'],
 ['Foo', 'C'],
 ('Bar', 'A'),
 ['Bar', 'B'],
 ['Bar', 'C']]

我尝试过以下两种方法:

df.columns = l 

生成一个非多级索引的数据框

平面数据框

index = pd.MultiIndex.from_tuples(l)
df.reindex(columns = index)

这个代码可以给出正确的索引,但数值消失了。 Disappeared values 我强烈感觉自己的方法不够Pythonic,也没有将列表转换为字典的意义。有什么办法可以正确地使用多重索引?

你的列表l看起来像是一个元组和列表的混合,因此使用MultiIndex.from_tuples()可能无法处理l中的列表。在调用index = pd.MultiIndex.from_tuples(l)之前,请尝试使用map(tuple, l)。 - Data_addict
1个回答

4

不要使用reindex,直接将列设置为您的新索引:

df.columns = pd.MultiIndex.from_tuples(l)

这将产生所需的结果。

reindex 不仅仅是替换索引值(尽管听起来像它应该做的事情,但文档并不是特别清楚)。相反,它会遍历您的新索引,选择与新索引匹配的行或列,并在没有旧索引与新索引匹配的情况下放置 NaN。这就是发生在您身上的事情:当 reindex 遇到不存在于原始数据帧中的 ['Foo', 'B'] 时,它会用 NaN 填充新数据帧中的列。

如果您的列总是遵循一致的模式(例如每三个二级列对应一个顶级列),您还可以使用 MultiIndex.from_product 来创建列索引:

iterables = [["Foo", "Bar"], ["A", "B", "C"]]
index = pd.MultiIndex.from_product(iterables)

如此接近,但我却没有看到,谢谢,它有效了!请问是否有更高效/Pythonic的方法来实现所需的结果? - Julien Marrec
1
很高兴能帮忙!更好的创建列索引的方法取决于您的列将如何变化。但是,如果它们始终看起来与您的示例类似,您可以使用MultiIndex.from_product(),我已将其添加到答案中。 - ASGM
MultiIndex.from_product()让我的生活轻松了很多!非常感谢! - Donovan Thomson

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接