加入收藏 | 设为首页 | 会员中心 | 我要投稿 李大同 (https://www.lidatong.com.cn/)- 科技、建站、经验、云计算、5G、大数据,站长网!
当前位置: 首页 > 编程开发 > Python > 正文

如何将多个Excel工作表导入到具有多处理功能的熊猫中?

发布时间:2020-12-17 17:41:00 所属栏目:Python 来源:网络整理
导读:我正在尝试在12核计算机上使用多处理程序来读取Excel文件–一个60MB的文件,每页15张,每行10,000行.使用pandas.read_csv导入所有工作表并且不进行并行化仍然需要大约33秒. 如果我使用pool.map(),它可以工作,但是比非并行版本要花更长的时间:150秒vs 33! 如

我正在尝试在12核计算机上使用多处理程序来读取Excel文件–一个60MB的文件,每页15张,每行10,000行.使用pandas.read_csv导入所有工作表并且不进行并行化仍然需要大约33秒.

如果我使用pool.map(),它可以工作,但是比非并行版本要花更长的时间:150秒vs 33!

如果我使用pool.map_async()需要36秒,但是我似乎无法访问(因此无法检查)输出!

我的问题是:

>我做错了什么? pool.map和pool.map_async都大致需要
即使我在read_single_sheet中将nrows = 10设置为同一时间
功能;同时读取10行还是10,000 –这是怎么回事
可能?
>如何获得pool.map_async()的结果?我努力了
输出= [数据帧中p的p.get()],但不起作用:

MapResult
object is not iterable

>这更多是受IO约束而不是CPU约束
问题?不过,为什么pool.map需要这么长时间?

从CSV读取相同的数据(每个Excel工作表已保存到单独的CSV)在我的计算机上需要2秒钟.但是,对于我需要做的事情,CSV并不是一个很好的选择.我通常有10到20个中型标签;与等待熊猫阅读它们相比,手动转换它们通常会花费更长的时间,此外,如果我收到更新的版本,则必须再次进行手动转换.

我知道我可以在Excel中使用VBA脚本自动将每张工作表保存为CSV,但是从Excel读取数据时,大多数情况下可以正确推断数据类型-CSV并非如此,尤其是对于日期(我的日期从不为ISO yyyy-mm-dd ):我必须确定日期字段,指定格式等-仅从Excel读取通常会更快.尤其是因为这些任务往往是一次性的:我将数据导入一次,如果收到更新,则可能导入两次或3次,将其存储在SQL中,然后从SQL中读取所有Python脚本.

我用来读取文件的代码是:

import numpy as np
import pandas as pd
import time
import multiprocessing
from multiprocessing import Pool
def parallel_read():
    pool = Pool(num_cores)
    # reads 1 row only,to retrieve column names and sheet names
    mydic = pd.read_excel('excel_write_example.xlsx',nrows=1,sheet_name=None)
    sheets =[]
    for d in mydic:
        sheets.extend([d])
    dataframes  = pool.map( read_single_sheet,sheets  )
    return dataframes

def parallel_read_async():
    pool = Pool(num_cores)
    # reads 1 row only,sheet_name=None)
    sheets =[]
    for d in mydic:
        sheets.extend([d])
    dataframes  = pool.map_async( read_single_sheet,sheets  ) 
    output = None
    # this below doesn`t work - can`t understand why
    output = [p.get() for p in dataframes]
    return output

def read_single_sheet(sheet):
    out = pd.read_excel('excel_write_example.xlsx',sheet_name=sheet )
    return out

num_cores = multiprocessing.cpu_count() 

if __name__=='__main__':
    start=time.time()
    out_p = parallel_read()
    time_par = time.time() -start

    out_as = parallel_read_async()
    time_as = time.time() - start - time_par

我用来创建Excel的代码是:

import numpy as np
import pandas as pd

sheets = 15
rows= int(10e3)

writer = pd.ExcelWriter('excel_write_example.xlsx')

def create_data(sheets,rows):
    df = {} # dictionary of dataframes
    for i in range(sheets):
        df[i] = pd.DataFrame(data= np.random.rand(rows,30) )
        df[i]['a'] = 'some long random text'
        df[i]['b'] = 'some more random text'
        df[i]['c'] = 'yet more text'
    return df

def data_to_excel(df,writer):
    for d in df:
        df[d].to_excel(writer,sheet_name = str(d),index=False)
    writer.close()

df = create_data(sheets,rows)
data_to_excel(df,writer)
最佳答案
我将其发布为答案,因为尽管它没有回答如何在Python中进行操作的问题,但它仍然提供了一种切实可行的替代方案,可以从实质上加快阅读速度,因此任何Python用户都可能会感兴趣.此外,它仅依赖于开源软件,并且要求用户仅学习R中的几个命令.

我的解决方案是:在R中执行!

我发布了here,它也显示了我的代码(非常少);基本上,在同一文件上,R的readxl用了5.6秒.回顾一下:

> xlsx中的Python:33秒
> CSV中的Python: 2秒
> xlsx中的R:5.6秒

该链接还有一个答案,表明并行化可以进一步加快处理速度.

我相信关键的区别在于pandas.read_csv依赖于C代码,而pandas.read_excel则依赖于更多的Python代码. R的readxl可能基于C.可以使用C分析器将xlsx文件导入Python,但是AFAIK到目前为止,尚无此类分析器.

这是一个可行的解决方案,因为在导入R后,您可以轻松地导出为保留有关数据类型的所有信息以及Python可以从中读取的格式(SQL,parquet等).并非每个人都可以使用SQL Server,但是镶木地板或sqlite之类的格式不需要任何其他软件.

因此,对工作流的更改很小:最初的数据加载(至少在我看来是一次性的)在R中,而其他所有内容继续在Python中.

我还注意到,使用R和DBI :: dbWriteTable将相同的工作表导出到SQL比使用熊猫快得多(4.25秒对18.4秒).

(编辑:李大同)

【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容!

    推荐文章
      热点阅读