探究 Pandas 讀取 Excel 文件報錯問題

問題描述

使用 Pandas 的 read_excel 方法讀取一個 16 萬行的 Excel 文件報 AssertionError 錯誤:

  "/Users/XXX/excel_test/venv/lib/python3.7/site-packages/xlrd/xlsx.py", line 637, in do_row
    assert 0 <= self.rowx < X12_MAX_ROWS
AssertionError

背后原理

Excel 文件有兩種默認格式末盔,在 Excel 2007 以前,使用擴展名為 .xls 格式的文件,這種文件格式是一種特定的二進制格式恨憎,最多支持 65,536 行(在 Excel 97 之前支持的最大行數(shù)是 16,384)蔼啦,256 列表格豪治。從 Excel 2007 版開始局齿,默認采用了基于 XML 的新的文件格式 .xlsx养铸,支持的表格行數(shù)達到了 1,048,576饭庞,列數(shù)達到了 16,384戒悠。需要注意的是,將 .xlsx 格式的文件轉(zhuǎn)換為 .xls 格式的文件時舟山,65,536 行和 256 列之后的數(shù)據(jù)都會被丟棄绸狐。

版本 最大行數(shù) 最大列數(shù) 文件格式
Excel 97 之前 16,384 256 .xls
Excel 97 到 Excel 2003 65,536 256 .xls
Excel 2007 及以后版本 1,048,576 16,384 .xlsx

Pandas 讀取 Excel 文件的引擎是 xlrdxlrd 在讀取 Excel 文件時累盗,xlrd/xlsx.py 文件的 637 行會對行號做斷言寒矿,判斷行號是否在 0 - 1,048,576(Excel支持的最大行數(shù)) 的范圍內(nèi)。這段代碼是這樣的:

row_number = row_elem.get('r')
if row_number is None: # Yes, it's optional.
    self.rowx += 1
    explicit_row_number = 0
    if self.verbosity and not self.warned_no_row_num:
        self.dumpout("no row number; assuming rowx=%d", self.rowx)
        self.warned_no_row_num = 1
else:
    self.rowx = row_number - 1
    explicit_row_number = 1
assert 0 <= self.rowx < X12_MAX_ROWS

代碼會從 Excel 文件中獲取 row_number若债,這個 row_number 是每一行的行號符相,正常文件行號從 1 開始,而出現(xiàn)問題的文件行號從 0 開始蠢琳,當行號為 0啊终,進入 else 語句镜豹,導致越界問題。

解決辦法

除了 xlrd蓝牲, Pandas 還支持 openpyxl(0.25 版)逛艰,openpyxl 是一個專門用來操作 .xlsx 格式文件的 Python 庫,和 xlrd 相比它的速度會慢一些搞旭,但是不會碰到上面所說的問題散怖。這是 openpyxl 中 reader/excel.py 文件處理行的代碼:

def parse_row(self, row):
    attrs = dict(row.attrib)

    if "r" in attrs:
        self.max_row = int(attrs['r'])
    else:
        self.max_row += 1
    keys = set(attrs)
    for key in keys:
        if key.startswith('{'):
            del attrs[key]

    keys = set(attrs)
    if keys != set(['r', 'spans']) and keys != set(['r']):
        # don't create dimension objects unless they have relevant information
        self.row_dimensions[attrs['r']] = attrs

    cells = [self.parse_cell(el) for el in row]
    return self.max_row, cells

openpyxl 在處理行時,并沒有對行號進行斷言肄渗,即使行號第一位是 0镇眷,也不會導致報錯,但這會導致第一行數(shù)據(jù)的缺失翎嫡,需要進行額外處理欠动。

使用 Pandas + openpyxl 讀取 Excel 文件

首先安裝 openpyxl

pip install openpyxl

Pandas 的 read_excel 方法中,有 engine 字段惑申,可以指定所使用的處理 Excel 文件的引擎具伍,填入 openpyxl,再讀取文件就可以了圈驼。

import pandas as pd


df = pd.read_excel('./data.xlsx', engine='openpyxl')
print(len(df))  # 160000

參考文檔

https://office-watch.com/2010/excel-a-history-of-rows-and-columns/

https://pandas.pydata.org/pandas-docs/stable/reference/api/pandas.read_excel.html

https://github.com/python-excel/xlrd/

https://bitbucket.org/openpyxl/openpyxl/src

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末人芽,一起剝皮案震驚了整個濱河市,隨后出現(xiàn)的幾起案子绩脆,更是在濱河造成了極大的恐慌萤厅,老刑警劉巖,帶你破解...
    沈念sama閱讀 207,113評論 6 481
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件靴迫,死亡現(xiàn)場離奇詭異惕味,居然都是意外死亡,警方通過查閱死者的電腦和手機玉锌,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 88,644評論 2 381
  • 文/潘曉璐 我一進店門名挥,熙熙樓的掌柜王于貴愁眉苦臉地迎上來,“玉大人主守,你說我怎么就攤上這事禀倔。” “怎么了丸逸?”我有些...
    開封第一講書人閱讀 153,340評論 0 344
  • 文/不壞的土叔 我叫張陵蹋艺,是天一觀的道長剃袍。 經(jīng)常有香客問我黄刚,道長,這世上最難降的妖魔是什么民效? 我笑而不...
    開封第一講書人閱讀 55,449評論 1 279
  • 正文 為了忘掉前任憔维,我火速辦了婚禮涛救,結(jié)果婚禮上,老公的妹妹穿的比我還像新娘业扒。我一直安慰自己检吆,他們只是感情好,可當我...
    茶點故事閱讀 64,445評論 5 374
  • 文/花漫 我一把揭開白布程储。 她就那樣靜靜地躺著蹭沛,像睡著了一般。 火紅的嫁衣襯著肌膚如雪章鲤。 梳的紋絲不亂的頭發(fā)上摊灭,一...
    開封第一講書人閱讀 49,166評論 1 284
  • 那天,我揣著相機與錄音败徊,去河邊找鬼帚呼。 笑死,一個胖子當著我的面吹牛皱蹦,可吹牛的內(nèi)容都是我干的煤杀。 我是一名探鬼主播,決...
    沈念sama閱讀 38,442評論 3 401
  • 文/蒼蘭香墨 我猛地睜開眼沪哺,長吁一口氣:“原來是場噩夢啊……” “哼沈自!你這毒婦竟也來了?” 一聲冷哼從身側(cè)響起辜妓,我...
    開封第一講書人閱讀 37,105評論 0 261
  • 序言:老撾萬榮一對情侶失蹤酥泛,失蹤者是張志新(化名)和其女友劉穎,沒想到半個月后嫌拣,有當?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體柔袁,經(jīng)...
    沈念sama閱讀 43,601評論 1 300
  • 正文 獨居荒郊野嶺守林人離奇死亡,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點故事閱讀 36,066評論 2 325
  • 正文 我和宋清朗相戀三年异逐,在試婚紗的時候發(fā)現(xiàn)自己被綠了捶索。 大學時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片。...
    茶點故事閱讀 38,161評論 1 334
  • 序言:一個原本活蹦亂跳的男人離奇死亡灰瞻,死狀恐怖腥例,靈堂內(nèi)的尸體忽然破棺而出,到底是詐尸還是另有隱情酝润,我是刑警寧澤燎竖,帶...
    沈念sama閱讀 33,792評論 4 323
  • 正文 年R本政府宣布,位于F島的核電站要销,受9級特大地震影響构回,放射性物質(zhì)發(fā)生泄漏。R本人自食惡果不足惜,卻給世界環(huán)境...
    茶點故事閱讀 39,351評論 3 307
  • 文/蒙蒙 一纤掸、第九天 我趴在偏房一處隱蔽的房頂上張望脐供。 院中可真熱鬧,春花似錦借跪、人聲如沸政己。這莊子的主人今日做“春日...
    開封第一講書人閱讀 30,352評論 0 19
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽歇由。三九已至,卻和暖如春果港,著一層夾襖步出監(jiān)牢的瞬間印蓖,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 31,584評論 1 261
  • 我被黑心中介騙來泰國打工京腥, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留赦肃,地道東北人。 一個月前我還...
    沈念sama閱讀 45,618評論 2 355
  • 正文 我出身青樓公浪,卻偏偏與公主長得像他宛,于是被迫代替她去往敵國和親。 傳聞我的和親對象是個殘疾皇子欠气,可洞房花燭夜當晚...
    茶點故事閱讀 42,916評論 2 344

推薦閱讀更多精彩內(nèi)容