在Python中使用MultiIndex和to_excel时在标头下方创建空行

时间:2018-09-25 11:50:30

标签: python pandas multi-index xlsxwriter

我正在尝试使用XlsxWriter的to_excel函数将Pandas数据框保存到excel文件中。

当我将数据帧打印到终端时,它会读取应有的内容,但是当我将其保存到excel并打开文件时,标题下面会有一个多余的空白行,该行不应存在。仅在使用MultiIndex作为标题时会发生这种情况,但是我需要它提供的分层标题,并且找不到解决方案。

下面是在线MultiIndex示例中的代码,该示例产生的结果与我正在研究的项目相同。任何解决方案将不胜感激。

import numpy as np
import pandas as pd
import xlsxwriter

tuples = [('bar', 'one'), ('bar', 'two'), ('baz', 'one'), ('baz', 'two'), ('foo', 'one'), ('foo', 'two'), ('qux', 'one'), ('qux', 'two')]

index = pd.MultiIndex.from_tuples(tuples, names=['first', 'second'])

iterables = [['bar', 'baz', 'foo', 'qux'], ['one', 'two']]

pd.MultiIndex.from_product(iterables, names=['first', 'second'])

df = pd.DataFrame(np.random.randn(3, 8), index=['A', 'B', 'C'], columns=index)

print(df)

writer = pd.ExcelWriter('test.xlsx', engine='xlsxwriter')
df.to_excel(writer, sheet_name='test1')

创建的excel输出: enter image description here

3 个答案:

答案 0 :(得分:2)

这很可能是熊猫中的错误。

有关建议的解决方案,请参见this question

  

没有简单的方法,而是通过读取xlsx来删除该行   再次。

还有一个指向GitHub issue的链接,解决了该主题。

所以我做了这个变通办法,它可能对您有所帮助:

df = pd.read_excel('/home/teoretic/test.xlsx', index_col=0)
df = df.drop(np.nan)  # <== dropping an empty row

rename_dct = dict.fromkeys(df.loc[:,df.columns.str.contains('^Unnamed')], '')
df = df.rename(columns=rename_dct)  # <== renaming 'Unnamed' columns to blank space 

writer = pd.ExcelWriter('/home/teoretic/test_new.xlsx', engine='xlsxwriter')
df.to_excel(writer, sheet_name='test1')

writer.close()

这是一个输出文件: enter image description here

答案 1 :(得分:1)

真的很感谢这个问题和@Teoretic的解决方法。

但是在我的情况下,Multiindex列的合并单元格非常有用,而@Teoretic丢失了这些单元格。我已经做了另一种变通方法,即在写之前将整个行隐藏起来,它可以工作,因此在这里包括它,以防对任何人有用。

writer = pd.ExcelWriter('test.xlsx', engine='xlsxwriter')
df.to_excel(writer, sheet_name='test1')
writer.sheets['test1'].set_row(2, None, None, {'hidden': True})
writer.save()

答案 2 :(得分:1)

通过使用空行读取文件,删除行并重新写入文件,我发现了使用包openpyxl的以下解决方法。我发现此方法的优点在于,它在MultiIndex列中保留了漂亮的合并单元格,并实际上从Excel文件中删除了空行。通过实际删除空白行,如果其余数据为数字,这将使您可以立即使用电子表格中的Excel筛选功能,而不必手动删除文件中的空白行。

result.data.pedidos[0]["previsao-entrega"]

虽然必须导入整个程序包来处理此问题并不理想,但我的用例要求我不要简单地隐藏丢失的行。如果您只需要隐藏空白行就可以逃脱,@ lrnzcig的解决方案会更好。