校园春色亚洲色图_亚洲视频分类_中文字幕精品一区二区精品_麻豆一区区三区四区产品精品蜜桃

主頁 > 知識庫 > pandas讀取excel時獲取讀取進度的實現

pandas讀取excel時獲取讀取進度的實現

熱門標簽:佛山通用400電話申請 廣東旅游地圖標注 京華圖書館地圖標注 淮安呼叫中心外呼系統如何 打印谷歌地圖標注 電話機器人貸款詐騙 蘇州人工外呼系統軟件 電話外呼系統招商代理 看懂地圖標注方法

寫在前面

QQ群里偶然看到群友問這個問題, pandas讀取大文件時怎么才能獲取進度? 我第一反應是: 除非pandas的read_excel等函數提供了回調函數的接口, 否則應該沒辦法做到. 搜索了一下官方文檔和網上的帖子, 果然是沒有現成的方案, 只能自己動手.

準備工作

確定方案

一開始我就確認了實現方案, 那就是增加回調函數. 這里現學現賣科普一下什么是回調函數. 簡單的說就是:

所使用的模塊里面, 會調用一個你給定的外部方法/函數, 就是回調函數. 拿本次的嘗試作為例子, 我會編寫一個"顯示進度函數", 通過傳參的方式傳入pd.read_excel, 這樣pd在讀取excel時, 會邊讀取邊調用"顯示進度函數". 為什么不直接在pd里面增加? 因為pd讀取excel文件時是阻塞的, 內部方法在被調用時無法拋出進度信息. (如有謬誤請指正)

理解讀取方式

先得了解一下pandas是怎么讀取excel的. 在pycharm里面按住control點擊read_excel, 再瀏覽一下代碼根據關鍵的函數繼續跳轉, 還是挺容易得到調用的路徑的.

最后OpenpyxlReader讀取excel的方法代碼如下. 很明顯重點就在其中的for循環里. 調用get_sheet_data時, 已經通過一系列方法獲得了目標sheet(這里細節不贅述), 然后在for循環里逐行讀取數據并返回data最后生成dataframe.

def get_sheet_data(self, sheet, convert_float: bool) -> List[List[Scalar]]:
        # GH 39001
        # Reading of excel file depends on dimension data being correct but
        # writers sometimes omit or get it wrong
        import openpyxl

        version = LooseVersion(get_version(openpyxl))

        # There is no good way of determining if a sheet is read-only
        # https://foss.heptapod.net/openpyxl/openpyxl/-/issues/1605
        is_readonly = hasattr(sheet, "reset_dimensions")

        if version >= "3.0.0" and is_readonly:
            sheet.reset_dimensions()

        data: List[List[Scalar]] = []
        last_row_with_data = -1
        for row_number, row in enumerate(sheet.rows):
            converted_row = [self._convert_cell(cell, convert_float) for cell in row]
            if not all(cell == "" for cell in converted_row):
                last_row_with_data = row_number
            data.append(converted_row)

        # Trim trailing empty rows
        data = data[: last_row_with_data + 1]

        if version >= "3.0.0" and is_readonly and len(data) > 0:
            # With dimension reset, openpyxl no longer pads rows
            max_width = max(len(data_row) for data_row in data)
            if min(len(data_row) for data_row in data)  max_width:
                empty_cell: List[Scalar] = [""]
                data = [
                    data_row + (max_width - len(data_row)) * empty_cell
                    for data_row in data
                ]

        return data

開始改動

這里直接暴力更改pandas庫源文件!(僅用于調試, 注意備份和保護自己的工作環境)

主程序代碼

編寫main.py, 代碼比較簡單, 相關功能我都用注釋作為解釋. 其中show_pd_read_excel_progress就是我編寫的回調函數, 通過命令行的方式輸出實時的讀取進度. 當然你如果編寫的是GUI程序比如PYQT5, 也可以在這個回調函數中發送signal給main UI, 做成progress bar或者其他的GUI樣式.

import pandas as pd
from datetime import datetime

'''
定義回調函數
cur: 讀取時的當前行數
tt: 讀取文件的總行數
'''
def show_pd_read_excel_progress(cur, tt):
    # 進度數值
    progress = " {:.2f}%".format(cur/tt*100)
    # 進度條
    bar = " ".join("█" for _ in range(int(cur/tt*100/10)))
    # 顯示進度
    print("\r進度:" + bar + progress, end="", flush=True)

# 記錄開始時間
t = datetime.now()
# 開始讀取excel
print("pd.read_excel: test_4.xlsx...")
xl_data = pd.read_excel("test_4.xlsx", callback=show_pd_read_excel_progress)
# 打印excel頭幾行
print(xl_data.head())
print("\n")
# 顯示花費的時間
print("Time spent:", datetime.now()-t)

修改pandas源碼

再自己觀察一下, 我在pd.read_excel方法的參數里增加了callback參數, 這個參數是原版read_excel方法里沒有的. 所以我們需要處理pandas源碼, 這個源碼在…/pandas/io/excel/_base.py中, pycharm中按住control點擊read_excel可以快速跳轉. 這個地方我增加了一個參數callback, 默認值為None. 下方io.parse同樣把callback參數傳遞給ExcelFile類.

def read_excel(
    io,
    sheet_name=0,
    header=0,
    names=None,
    index_col=None,
    usecols=None,
    squeeze=False,
    dtype=None,
    engine=None,
    converters=None,
    true_values=None,
    false_values=None,
    skiprows=None,
    nrows=None,
    na_values=None,
    keep_default_na=True,
    na_filter=True,
    verbose=False,
    parse_dates=False,
    date_parser=None,
    thousands=None,
    comment=None,
    skipfooter=0,
    convert_float=True,
    mangle_dupe_cols=True,
    storage_options: StorageOptions = None,
    callback = None, # 增加callback參數
):

    should_close = False
    if not isinstance(io, ExcelFile):
        should_close = True
        io = ExcelFile(io, storage_options=storage_options, engine=engine)
    elif engine and engine != io.engine:
        raise ValueError(
            "Engine should not be specified when passing "
            "an ExcelFile - ExcelFile already has the engine set"
        )

    try:
        data = io.parse(
            sheet_name=sheet_name,
            header=header,
            names=names,
            index_col=index_col,
            usecols=usecols,
            squeeze=squeeze,
            dtype=dtype,
            converters=converters,
            true_values=true_values,
            false_values=false_values,
            skiprows=skiprows,
            nrows=nrows,
            na_values=na_values,
            keep_default_na=keep_default_na,
            na_filter=na_filter,
            verbose=verbose,
            parse_dates=parse_dates,
            date_parser=date_parser,
            thousands=thousands,
            comment=comment,
            skipfooter=skipfooter,
            convert_float=convert_float,
            mangle_dupe_cols=mangle_dupe_cols,
            callback = callback, # 增加callback參數
        )
    finally:
        # make sure to close opened file handles
        if should_close:
            io.close()
    return data
... # 省略代碼

瀏覽一下ExcelFile類(還在_base.py中)的代碼, 這個類會根據文件類型選擇引擎, 我讀取的是xlsx文件, 所以會跳轉到openpyxl并把所有的參數傳遞過去, 這個類不用處理. 下面跳轉到_openpyxl.py中看一下OpenpyxlReader類, 這個類是繼承BaseExcelReader類(在_base.py中)的, 所以還是得回去看一下BaseExcelReader, 并修改一下參數, 增加callback(如下2處).

def parse(
        self,
        sheet_name=0,
        header=0,
        names=None,
        index_col=None,
        usecols=None,
        squeeze=False,
        dtype=None,
        true_values=None,
        false_values=None,
        skiprows=None,
        nrows=None,
        na_values=None,
        verbose=False,
        parse_dates=False,
        date_parser=None,
        thousands=None,
        comment=None,
        skipfooter=0,
        convert_float=True,
        mangle_dupe_cols=True,
        callback = None, # 增加callback參數
        **kwds,
    ):
... # 省略代碼
for asheetname in sheets:
            if verbose:
                print(f"Reading sheet {asheetname}")

            if isinstance(asheetname, str):
                sheet = self.get_sheet_by_name(asheetname)
            else:  # assume an integer if not a string
                sheet = self.get_sheet_by_index(asheetname)

            data = self.get_sheet_data(sheet, convert_float, callback) # 傳遞callback參數給get_sheet_data方法
            usecols = maybe_convert_usecols(usecols)
... # 省略代碼

好了, 終于到重點了, 我們跳轉到get_sheet_data方法, 并做對應修改(方法參數, 獲取總行數, 調用回調函數). 思路非常清晰, 通過一頓操作, 終于千里迢迢把callback給一層層傳遞過來了, 所以在一行行讀取excel時, 可以調用并顯示進度了.

def get_sheet_data(self, sheet, convert_float: bool, callback) -> List[List[Scalar]]: # 傳遞參數增加callback
        # GH 39001
        # Reading of excel file depends on dimension data being correct but
        # writers sometimes omit or get it wrong
        import openpyxl
				# 獲取sheet的總行數
        max_row = sheet.max_row
        print("sheet_max_row:", sheet.max_row)

        version = LooseVersion(get_version(openpyxl))

        # There is no good way of determining if a sheet is read-only
        # https://foss.heptapod.net/openpyxl/openpyxl/-/issues/1605
        is_readonly = hasattr(sheet, "reset_dimensions")

        if version >= "3.0.0" and is_readonly:
            sheet.reset_dimensions()

        data: List[List[Scalar]] = []
        last_row_with_data = -1
        for row_number, row in enumerate(sheet.rows):
						# 調用回調函數
            if callback is not None:
                callback(row_number+1, max_row)
            converted_row = [self._convert_cell(cell, convert_float) for cell in row]
            if not all(cell == "" for cell in converted_row):
                last_row_with_data = row_number
            data.append(converted_row)

        # Trim trailing empty rows
        data = data[: last_row_with_data + 1]

        if version >= "3.0.0" and is_readonly and len(data) > 0:
            # With dimension reset, openpyxl no longer pads rows
            max_width = max(len(data_row) for data_row in data)
            if min(len(data_row) for data_row in data)  max_width:
                empty_cell: List[Scalar] = [""]
                data = [
                    data_row + (max_width - len(data_row)) * empty_cell
                    for data_row in data
                ]

        return data

運行測試

運行一下main.py, 效果如下, 實時顯示進度功能已經實現, 且會計算出讀取所花費的時間. 如果你是要讀取csv或者sql之類的, 也可以照貓畫虎.

優化和應用

  • 前面也說過直接修改pandas源碼是非常不科學的操作, 這會破壞已有的編程環境, 且源碼換到別的機器上還得重新在修改一遍
  • 也嘗試過用繼承+重寫pandas, 不過水平有限沒有成功, 希望大家指點
  • 實測print進度條會非常費時間, 當然也不需要每讀一行excel都更新一次進度條, 定時(比如每秒刷一次)或者定量(每n行, 或者每1%進度刷新一次)比較合理
  • 讀取大規模數據時, 頻繁調用回調函數肯定會耽誤效率, 不過如果是GUI程序或者給其他人使用的, 有實時進度肯定會改善用戶體驗, 其中優劣需要coder自己權衡

到此這篇關于pandas讀取excel時獲取讀取進度的實現的文章就介紹到這了,更多相關pandas讀取excel讀取內容請搜索腳本之家以前的文章或繼續瀏覽下面的相關文章希望大家以后多多支持腳本之家!

您可能感興趣的文章:
  • 教你使用Pandas直接核算Excel中的快遞費用
  • Python入門之使用pandas分析excel數據
  • pandas快速處理Excel,替換Nan,轉字典的操作
  • pandas讀取excel,txt,csv,pkl文件等命令的操作
  • python pandas模糊匹配 讀取Excel后 獲取指定指標的操作
  • pandas針對excel處理的實現
  • 關于Python 解決Python3.9 pandas.read_excel(‘xxx.xlsx‘)報錯的問題
  • 解決使用Pandas 讀取超過65536行的Excel文件問題
  • 利用Python pandas對Excel進行合并的方法示例
  • Python pandas對excel的操作實現示例
  • pandas to_excel 添加顏色操作
  • 解決python pandas讀取excel中多個不同sheet表格存在的問題
  • Python pandas如何向excel添加數據
  • pandas中的ExcelWriter和ExcelFile的實現方法
  • pandas實現excel中的數據透視表和Vlookup函數功能代碼
  • Python使用Pandas讀寫Excel實例解析
  • pandas將多個dataframe以多個sheet的形式保存到一個excel文件中
  • 利用python Pandas實現批量拆分Excel與合并Excel

標簽:中山 畢節 駐馬店 湖州 江蘇 呼和浩特 衡水 股票

巨人網絡通訊聲明:本文標題《pandas讀取excel時獲取讀取進度的實現》,本文關鍵詞  pandas,讀取,excel,時,獲取,;如發現本文內容存在版權問題,煩請提供相關信息告之我們,我們將及時溝通與處理。本站內容系統采集于網絡,涉及言論、版權與本站無關。
  • 相關文章
  • 下面列出與本文章《pandas讀取excel時獲取讀取進度的實現》相關的同類信息!
  • 本頁收集關于pandas讀取excel時獲取讀取進度的實現的相關信息資訊供網民參考!
  • 推薦文章
    校园春色亚洲色图_亚洲视频分类_中文字幕精品一区二区精品_麻豆一区区三区四区产品精品蜜桃
    秋霞午夜av一区二区三区| 日本不卡的三区四区五区| 国产在线播放一区三区四| www一区二区| 亚洲永久精品大片| 91丝袜美腿高跟国产极品老师| 久久亚洲精品国产精品紫薇| 视频在线在亚洲| 欧美日韩一区三区| 亚洲一区二区成人在线观看| 欧美性受极品xxxx喷水| 亚洲综合无码一区二区| 91小视频免费看| 久久精品一区二区三区不卡| 久久精品国产99| 欧美本精品男人aⅴ天堂| 精品一区中文字幕| 精品成人一区二区三区四区| 看电影不卡的网站| 欧美mv日韩mv| 国产激情一区二区三区| 久久这里只有精品首页| 韩国v欧美v亚洲v日本v| 国产三区在线成人av| 成人污视频在线观看| 中文字幕在线一区二区三区| 不卡的av电影| 国产精品久久久久一区二区三区| 成人免费视频播放| 亚洲欧美日韩小说| 欧美丝袜第三区| 人妖欧美一区二区| 久久综合色天天久久综合图片| 国内精品久久久久影院一蜜桃| 精品久久久久久久久久久久包黑料 | 久久夜色精品国产欧美乱极品| 久久99蜜桃精品| 国产日韩欧美精品一区| 99re热这里只有精品免费视频| 亚洲精品五月天| 欧美一区二区三区的| 久久se精品一区二区| 2019国产精品| 91捆绑美女网站| 美国精品在线观看| 国产精品久久免费看| 色国产精品一区在线观看| 亚洲欧美中日韩| 91国在线观看| 蜜臀久久99精品久久久画质超高清| 久久久久国色av免费看影院| 99久久久久久| 秋霞电影网一区二区| 日本一区二区三区在线观看| 色综合久久久久综合体| 久久99久久久久| 中文字幕中文乱码欧美一区二区| 欧美高清视频www夜色资源网| 韩国理伦片一区二区三区在线播放| 亚洲人成伊人成综合网小说| 欧美高清你懂得| 99精品视频免费在线观看| 精品综合免费视频观看| 国产亚洲一区二区在线观看| 欧美日韩亚洲高清一区二区| 成人在线视频一区| 美国十次了思思久久精品导航| 亚洲免费视频中文字幕| 26uuu国产电影一区二区| 在线亚洲+欧美+日本专区| 九九在线精品视频| 亚洲成a人片综合在线| 国产精品久久三区| 久久夜色精品一区| 欧美精品一二三| 色婷婷激情一区二区三区| 丁香天五香天堂综合| 免费人成精品欧美精品| 夜夜揉揉日日人人青青一国产精品| 911精品国产一区二区在线| 国产99久久精品| 九九九久久久精品| 日韩在线一区二区三区| 一区二区三区不卡在线观看| 欧美国产精品v| 精品国产三级a在线观看| 91精品国产欧美一区二区成人 | 久久久久久一二三区| 91.麻豆视频| 欧美性生活一区| 91在线小视频| 99亚偷拍自图区亚洲| 国产精品99久久久久| 国产揄拍国内精品对白| 美女视频黄久久| 青青草原综合久久大伊人精品 | 亚洲欧美另类小说视频| 欧美国产综合色视频| 亚洲精品在线观看网站| 欧美日韩国产区一| 欧美性三三影院| 欧美视频中文一区二区三区在线观看| 色婷婷综合久久久久中文一区二区 | 日韩精品一级中文字幕精品视频免费观看 | 日韩精品91亚洲二区在线观看| 91福利视频久久久久| 亚洲综合一区在线| 欧美视频在线观看一区二区| 在线亚洲一区观看| 欧美亚洲动漫制服丝袜| 欧美亚洲动漫制服丝袜| 欧美日韩亚洲另类| 欧美一区二区三区小说| 99久久久国产精品| 欧美另类变人与禽xxxxx| 国产欧美视频一区二区三区| 亚洲一级在线观看| 懂色一区二区三区免费观看 | 日韩精品每日更新| 国产黑丝在线一区二区三区| 99视频一区二区| 欧美一级理论片| 中文字幕av资源一区| 天堂午夜影视日韩欧美一区二区| www.亚洲激情.com| 久久超碰97中文字幕| 亚洲影视资源网| 成人av综合一区| 精品精品欲导航| 偷窥少妇高潮呻吟av久久免费| 六月丁香婷婷久久| 国产一区二区三区日韩| 欧美无乱码久久久免费午夜一区| 国产日韩欧美综合在线| 日韩va亚洲va欧美va久久| 日本福利一区二区| 欧美激情一区二区三区不卡| 久久av中文字幕片| 91精品国产综合久久久久久| 亚洲欧洲av在线| 成人高清视频免费观看| 久久美女艺术照精彩视频福利播放 | 日韩精品午夜视频| 欧美日韩一卡二卡| 亚洲欧美综合色| 白白色 亚洲乱淫| 久久精品一区八戒影视| 五月综合激情日本mⅴ| 91免费版在线看| 精品国产一区久久| 亚洲欧美一区二区三区久本道91| 国产jizzjizz一区二区| 久久久亚洲欧洲日产国码αv| 免费av网站大全久久| 成人精品视频一区二区三区| 国产亚洲精品久| 国产精品一区二区你懂的| 精品成人一区二区| 日韩精品成人一区二区三区| 欧美日韩一级二级三级| 午夜激情一区二区| 91精品久久久久久久99蜜桃| 五月婷婷欧美视频| 欧美日韩免费观看一区二区三区| 一区二区三区欧美日韩| 在线观看不卡视频| 午夜久久久久久久久| 欧美久久一二区| 麻豆91小视频| 26uuu亚洲综合色欧美| 国产一区福利在线| 亚洲欧美日韩人成在线播放| 555www色欧美视频| 国产激情一区二区三区| 亚洲一区二区三区美女| 欧美成人一级视频| 99久久婷婷国产精品综合| 石原莉奈在线亚洲三区| 久久久久久久久97黄色工厂| 在线观看欧美日本| 另类小说色综合网站| 国产精品国产三级国产三级人妇| 91高清视频免费看| 国产精品综合一区二区| 亚洲国产成人va在线观看天堂| 精品国产乱码久久| 色香蕉久久蜜桃| 精品一二线国产| 一区二区三区在线视频观看| 日韩一区二区三区视频| 99国产精品久久| 久久精品国内一区二区三区 | 欧美aaaaaa午夜精品| 国产精品无遮挡| 欧美精品黑人性xxxx| 成人aa视频在线观看| 青青草原综合久久大伊人精品| 亚洲欧美一区二区三区久本道91| 日韩欧美在线观看一区二区三区| 91视频免费观看|