Pandas,使用 merge_cells=False 从 excel 恢复多索引

Posted

技术标签:

【中文标题】Pandas,使用 merge_cells=False 从 excel 恢复多索引【英文标题】:Pandas, restore multiindex from excel with merge_cells=False 【发布时间】:2019-12-16 05:08:46 【问题描述】:

当我将多索引和多列数据框保存到 Excel 时。我有两个选择。有和没有merge_cells=False。这个 SO Question 很好地解释了这一点:

Avoid merged cells in pandas to_excel method

如果我确实使用 merge_cells=False,我将不得不使用 ffil 用前一个单元格填充合并的单元格,这可能有点危险,因为如果真的有 Nans(不是从合并的单元格中出现),他们可能(错误地)被覆盖。

我可以使用df.to_excel(writer, merge_cells=False) 生成一个整洁的格式

像这样的多索引数据帧 (https://pastebin.com/Me0QhwUy):

      AA1 AA2 CB1 BB2 CC1      
        a   a   b   b   c     d
    ng/mL N/A N/A  mL N/A EU/mL
0 1                            
A 1     1   1   1   1   1     1
  2     1   1   1   1   1     1
B 1     1   1   1   1   1     1
  2     1   1   1   1   1     1
C 1     1   1   1   1   1     1
  2     1   1   1   1   1     1

会变成(读取保存的excel后):

writer = pd.ExcelWriter('test.xlsx')
df.to_excel(writer, merge_cells=False)
writer.save()
writer.close()

df2 = pd.read_excel('test.xlsx')

   0  1  AA1.a.ng/mL  AA2.a.N/A  CB1.b.N/A  BB2.b.mL  CC1.c.N/A  CC1.d.EU/mL
0  A  1            1          1          1         1          1            1
1  A  2            1          1          1         1          1            1
2  B  1            1          1          1         1          1            1
3  B  2            1          1          1         1          1            1
4  C  1            1          1          1         1          1            1
5  C  2            1          1          1         1          1            1            

我知道函数wide to long,但这个函数确实假设了这里不存在的常见存根名称。

如何从保存的 excel 中恢复原始多索引数据框(使用 merged_cell=False)?

【问题讨论】:

【参考方案1】:

read_excel 中使用参数index_colMultiIndex,然后为MultiIndex 使用Series.str.split

d = ('AA1', 'a', 'ng/mL'): ('A', 1): 1,
  ('A', 2): 1,
  ('B', 1): 1,
  ('B', 2): 1,
  ('C', 1): 1,
  ('C', 2): 1,
 ('AA2', 'a', 'N/A'): ('A', 1): 1,
  ('A', 2): 1,
  ('B', 1): 1,
  ('B', 2): 1,
  ('C', 1): 1,
  ('C', 2): 1,
 ('BB2', 'b', 'mL'): ('A', 1): 1,
  ('A', 2): 1,
  ('B', 1): 1,
  ('B', 2): 1,
  ('C', 1): 1,
  ('C', 2): 1,
 ('CB1', 'b', 'N/A'): ('A', 1): 1,
  ('A', 2): 1,
  ('B', 1): 1,
  ('B', 2): 1,
  ('C', 1): 1,
  ('C', 2): 1,
 ('CC1', 'c', 'N/A'): ('A', 1): 1,
  ('A', 2): 1,
  ('B', 1): 1,
  ('B', 2): 1,
  ('C', 1): 1,
  ('C', 2): 1,
 ('CC1', 'd', 'EU/mL'): ('A', 1): 1,
  ('A', 2): 1,
  ('B', 1): 1,
  ('B', 2): 1,
  ('C', 1): 1,
  ('C', 2): 1

df = pd.DataFrame(d)
print (df)

      AA1 AA2 BB2 CB1 CC1      
        a   a   b   b   c     d
    ng/mL N/A  mL N/A N/A EU/mL
A 1     1   1   1   1   1     1
  2     1   1   1   1   1     1
B 1     1   1   1   1   1     1
  2     1   1   1   1   1     1
C 1     1   1   1   1   1     1

writer = pd.ExcelWriter('test.xlsx')
df.to_excel(writer, merge_cells=False)
writer.save()
writer.close()

df2 = pd.read_excel('test.xlsx', index_col=[0,1])
df2.columns = df2.columns.str.split('.', expand=True)
print (df2)
      AA1 AA2 BB2 CB1 CC1      
        a   a   b   b   c     d
    ng/mL N/A  mL N/A N/A EU/mL
A 1     1   1   1   1   1     1
  2     1   1   1   1   1     1
B 1     1   1   1   1   1     1
  2     1   1   1   1   1     1
C 1     1   1   1   1   1     1
  2     1   1   1   1   1     1

【讨论】:

也许我的问题已经过时了。由于这个老问题***.com/questions/22937650/…,我很担心,但我刚刚尝试过,pandas 完美地读取了合并的单元格。

以上是关于Pandas,使用 merge_cells=False 从 excel 恢复多索引的主要内容,如果未能解决你的问题,请参考以下文章

pandas - DataFrame 写入同一张excel表

python pandas to_excel 高级玩法

pandas apply

Pandas:打印缺少值的列名

如何在 Python 中按多列对 Pandas DataFrame 进行排序

TYPO3 Fluidcontent:如何在对象内使用 FAL