如何使用 df.to_csv 为多索引数据帧 python3 格式化 csv 文件

Posted

技术标签:

【中文标题】如何使用 df.to_csv 为多索引数据帧 python3 格式化 csv 文件【英文标题】:How to format the csv file with df.to_csv for a multiindex dataframe, python3 【发布时间】:2021-11-08 00:12:06 【问题描述】:

我有一个多索引数据框,

>>> df
       a1      a2    
       b1  b2  b1  b2
c1 d1  11  21  31  41
   d2  12  22  32  42
c2 d1  13  23  33  43
   d2  14  24  34  44

它有 2 级标题和 2 级索引。如果我直接使用代码df.to_csv('test_file.csv'),那么文件test_file.csv的格式是

,,a1,a1,a2,a2
,,b1,b2,b1,b2
c1,d1,11,21,31,41
c1,d2,12,22,32,42
c2,d1,13,23,33,43
c2,d2,14,24,34,44

不过,我想把它改成

    删除第一级标题中的重复项 删除整个第一级索引,并为第一级索引中的每个索引创建一个空行。

想要的格式是:

,a1,,a2,
,b1,b2,b1,b2
c1,,,,,
d1,11,21,31,41
d2,12,22,32,42
c2,,,,,
d1,13,23,33,43
d2,14,24,34,44

你能告诉我怎么做吗?谢谢! 请使用下面的代码。

import pandas as pd


df = pd.DataFrame(
    
        ('a1', 'b1'): [11, 12, 13, 14],
        ('a1', 'b2'): [21, 22, 23, 24],
        ('a2', 'b1'): [31, 32, 33, 34],
        ('a2', 'b2'): [41, 42, 43, 44],
    ,
    index=pd.MultiIndex.from_tuples([
        ('c1', 'd1'),
        ('c1', 'd2'),
        ('c2', 'd1'),
        ('c2', 'd2'),
    ]),
)

print(df)
df.to_csv('my_test_file.csv')

【问题讨论】:

【参考方案1】:

这是一个可行的解决方案。它使用辅助函数删除重复的连续标签,并使用groupy+apply+pandas.concat 将多索引级别移动为额外的空行:

def remove_consecutive(l):
    '''replaces consecutive items in "l" with empty string'''
    from itertools import groupby, chain
    return tuple(chain(*([k]+['']*(len(list(g))-1) for k,g in groupby(l))))

(df.groupby(level=0)
   # below to shift level=0 as new row
   .apply(lambda g: pd.concat([pd.DataFrame([],
                                            index=[g.name],
                                            columns=g.columns),
                               g.droplevel(0)]))
  .droplevel(0)
  # below to remove the duplicate column names
  .T # unfortunately there is no set_index equivalent for columns, so transpose before/after
  .set_index(pd.MultiIndex.from_arrays(list(map(remove_consecutive, zip(*df.columns)))))
  .T
  # export
  .to_csv('filename.csv')
)

输出:

,a1,,a2,
,b1,b2,b1,b2
c1,,,,
d1,11,21,31,41
d2,12,22,32,42
c1,,,,
d1,13,23,33,43
d2,14,24,34,44

【讨论】:

非常感谢您提供的有用代码。有用!唯一的错误是index=[name],应该是index=[g.name]。我还从你那里学到了使用() 来分隔不同行的方法调用。 :)

以上是关于如何使用 df.to_csv 为多索引数据帧 python3 格式化 csv 文件的主要内容,如果未能解决你的问题,请参考以下文章

如何计算熊猫中重新采样的多索引数据帧

将 collections.Counters 的组合频率从数据帧多索引转换为字符串

将多索引数据帧的索引值提取为python中的简单列表

如何在不合并索引的情况下连接具有不同多索引的两个数据帧?

如何从包含数据和时间作为索引的多索引数据帧中查询[重复]

使用 pandas 连接多索引列