我修复了Pandas包的一个bug
你好,我是zhenguo
这篇文章介绍Pandas中一个bug,昨天研究了此bug出现的原因,及修改措施。感兴趣的可以看一下,获取在日后能对你有一定帮助。
1 还原这个bug
导出含有层级关系的列头时,会多写出一个空行,此bug稳定出现。
2 定位问题
经过调试发现,锁定此bug出现的位置到
excel.py
模块,如下所示:理一理excel.py模块封装的方法,经过调试发现,
write
方法中下面几行代码是关键逻辑: formatted_cells = self.get_formatted_cells()
writer.write_cells(
formatted_cells,
sheet_name,
startrow=startrow,
startcol=startcol,
freeze_panes=freeze_panes,
)
写入到excel过程,实际是逐个单元格写入到excel过程,主要调用封装的
get_formatted_cells
方法得到formatted_cells
再进去看看
get_formatted_cells
方法,它使用chain
串接了两个生成器,然后逐一yield吐出cell: def get_formatted_cells(self):
for cell in itertools.chain(self._format_header(), self._format_body()):
cell.val = self._format_value(cell.val)
yield cell
而串接的这两个迭代器,一个是
self._format_header()
,另一个是self._format_body()
经过调试,在这里就能找到bug出现的原因,
self._format_body()
是有问题的,经过格式化数据域部分。拿文章一开始的case举例,取值为a的单元格对应的行索引被错误的标记为3,注意行索引是从0开始的。很明显,实际应该是23 修复bug
找到原因后,进一步下钻到底层方法,经过调试,进一步锁定到
self._format_body()
中调用的 _format_regular_rows
方法,里面与行编号相关联的属性是self.rowcounter
,所以重点关注与它相关的写入逻辑: def _format_regular_rows(self):
has_aliases = isinstance(self.header, (tuple, list, np.ndarray, Index))
if has_aliases or self.header:
self.rowcounter += 1
# output index and index_label?
if self.index:
# check aliases
# if list only take first as this is not a MultiIndex
if self.index_label and isinstance(
self.index_label, (list, tuple, np.ndarray, Index)
):
index_label = self.index_label[0]
# if string good to go
elif self.index_label and isinstance(self.index_label, str):
index_label = self.index_label
else:
index_label = self.df.index.names[0]
if isinstance(self.columns, ABCMultiIndex):
self.rowcounter += 1
一共有2处可能的写入,其中第二处写入,也就是上面代码块的最后两行,是bug出现的原因。经过仔细分析,在级联表头(ABCMultiIndex)写入excel场景中,行索引已经在
self._format_header()
中,行索引已经被加1,所以再在此处对其加1,是重复的:if isinstance(self.columns, ABCMultiIndex):
self.rowcounter += 1
所以修改方法就是对其标注即可。
4 修复bug后
修复后,经过测试级联列头、单列头,都正常,不再有多余的空行。
以上,此bug我已经提交到github的pandas中,希望帮助到更多的开发者。
我是zhenguo,最后希望点赞+转发~
最新评论
推荐文章
作者最新文章
你可能感兴趣的文章
Copyright Disclaimer: The copyright of contents (including texts, images, videos and audios) posted above belong to the User who shared or the third-party website which the User shared from. If you found your copyright have been infringed, please send a DMCA takedown notice to [email protected]. For more detail of the source, please click on the button "Read Original Post" below. For other communications, please send to [email protected].
版权声明:以上内容为用户推荐收藏至CareerEngine平台,其内容(含文字、图片、视频、音频等)及知识版权均属用户或用户转发自的第三方网站,如涉嫌侵权,请通知[email protected]进行信息删除。如需查看信息来源,请点击“查看原文”。如需洽谈其它事宜,请联系[email protected]。
版权声明:以上内容为用户推荐收藏至CareerEngine平台,其内容(含文字、图片、视频、音频等)及知识版权均属用户或用户转发自的第三方网站,如涉嫌侵权,请通知[email protected]进行信息删除。如需查看信息来源,请点击“查看原文”。如需洽谈其它事宜,请联系[email protected]。