吾爱破解 - 52pojie.cn

 找回密码
 注册[Register]

QQ登录

只需一步,快速开始

查看: 643|回复: 7
收起左侧

[求助] 求助python代码拆分excel另存为csv运行速度太慢

[复制链接]
heiyahua 发表于 2023-6-9 10:18
本帖最后由 heiyahua 于 2023-6-9 10:29 编辑

代码如下,在处理较大的excel文件时,代码运行特别耗时间,求助大佬们帮忙给点建议,谢谢。
[Python] 纯文本查看 复制代码
import os
import pandas as pd
import logging
import time
from concurrent.futures import ThreadPoolExecutor

# 获取当前文件夹路径
current_dir = os.getcwd()

# 获取当前文件夹内的所有Excel文件
excel_files = [file for file in os.listdir(current_dir) if file.endswith('.xlsx') or file.endswith('.xls')]

# 设置openpyxl日志级别为ERROR,忽略Workbook无默认样式的告警
logging.getLogger('openpyxl').setLevel(logging.ERROR)

# 设置pandas不输出警告信息
pd.options.mode.chained_assignment = None  # 取消chained_assignment警告
pd.options.mode.use_inf_as_na = True  # 将inf视为缺失值,避免警告输出

# 定义处理Excel文件的函数
def process_excel(excel_file):
    # 创建以Excel文件命名的文件夹
    excel_folder = os.path.splitext(excel_file)[0]
    if not os.path.exists(excel_folder):
        os.makedirs(excel_folder)
    
    # 读取Excel文件中的sheet名
    excel = pd.ExcelFile(excel_file)
    sheet_names = excel.sheet_names
    
    # 初始化上一个保存文件的时间
    prev_time = time.time()
    
    # 遍历每个sheet,将第三行及以下的内容保存为CSV文件
    for sheet_name in sheet_names:
        # 读取Excel文件中的每个sheet,跳过前两行
        df_sheet = pd.read_excel(excel_file, sheet_name=sheet_name, skiprows=2, engine='openpyxl')
        
        # 将sheet名作为文件名,保存为CSV文件
        csv_file_name = os.path.join(excel_folder, f'{sheet_name}.csv')
        df_sheet.to_csv(csv_file_name, index=False,encoding='gbk')
        
        # 计算并打印保存文件所使用的时间
        current_time = time.time()
        elapsed_time = current_time - prev_time
        print(f'Saved {csv_file_name} successfully. Elapsed time: {elapsed_time:.2f} seconds')
        prev_time = current_time

# 使用多线程处理Excel文件
with ThreadPoolExecutor(max_workers=16) as executor:  # 可根据需要设置最大线程数
    executor.map(process_excel, excel_files)
print('拆分完成!')

发帖前要善用论坛搜索功能,那里可能会有你要找的答案或者已经有人发布过相同内容了,请勿重复发帖。

ifdess 发表于 2023-6-9 11:27
在处理较大的Excel文件时,可以尝试以下几个优化方法:

1. 逐步读取数据:使用`pd.read_excel`函数时,可以指定`chunksize`参数来逐步读取数据,而不是一次性读取整个文件。这样可以减少内存的使用,并且降低整体的运行时间。例如,可以将`pd.read_excel(excel_file, sheet_name=sheet_name, skiprows=2, engine='openpyxl')`修改为`pd.read_excel(excel_file, sheet_name=sheet_name, skiprows=2, engine='openpyxl', chunksize=1000)`,并在处理每个chunk时逐步处理数据。

2. 并行处理:使用多线程或多进程来并行处理多个Excel文件。你已经使用了`ThreadPoolExecutor`来实现多线程处理,可以通过增加`max_workers`参数的值来增加线程数,以加快处理速度。请注意,线程数并不是越多越好,具体最佳值取决于你的系统配置和处理的Excel文件数量。

3. 优化写入文件:在当前代码中,每个线程都会将处理后的数据写入独立的CSV文件。写入文件可能会成为性能瓶颈,特别是当文件数量较大时。你可以尝试将数据保存在内存中,而不是写入磁盘,直到所有数据处理完成后再统一写入磁盘。可以使用`StringIO`或`BytesIO`来创建内存文件对象,并将数据写入该对象,最后再将整个对象一次性写入磁盘。

4. 优化循环逻辑:遍历每个sheet时,你可以尝试减少不必要的操作。例如,可以将保存文件的时间记录放在循环外部,而不是每次循环内部计算。这样可以减少不必要的时间开销。

尝试应用上述优化方法,可以提高处理较大Excel文件的效率。记得在实施这些改进之前,对代码进行备份,以防意外情况发生。
longteng9421 发表于 2023-6-9 11:51
[Python] 纯文本查看 复制代码
import os
import pandas as pd
import logging
import time
from concurrent.futures import ThreadPoolExecutor

# 获取当前文件夹路径
current_dir = os.getcwd()

# 获取当前文件夹内的所有Excel文件
excel_files = [file for file in os.listdir(current_dir) if file.endswith('.xlsx') or file.endswith('.xls')]

# 设置openpyxl日志级别为ERROR,忽略Workbook无默认样式的告警
logging.getLogger('openpyxl').setLevel(logging.ERROR)

# 设置pandas不输出警告信息
pd.options.mode.chained_assignment = None  # 取消chained_assignment警告
pd.options.mode.use_inf_as_na = True  # 将inf视为缺失值,避免警告输出

# 定义处理Excel文件的函数
def process_excel(excel_file):
    # 创建以Excel文件命名的文件夹
    excel_folder = os.path.splitext(excel_file)[0]
    if not os.path.exists(excel_folder):
        os.makedirs(excel_folder)

    # 读取Excel文件中的sheet名
    excel = pd.ExcelFile(excel_file)
    sheet_names = excel.sheet_names

    # 初始化上一个保存文件的时间
    prev_time = time.time()

    # 遍历每个sheet,将第三行及以下的内容保存为CSV文件
    for sheet_name in sheet_names:
        # 读取Excel文件中的每个sheet,跳过前两行
        df_sheet = pd.read_excel(excel_file, sheet_name=sheet_name, skiprows=2, engine='openpyxl')

        # 将sheet名作为文件名,保存为CSV文件
        csv_file_name = os.path.join(excel_folder, f'{sheet_name}.csv')
        df_sheet.to_csv(csv_file_name, index=False, encoding='gbk')

        # 计算并打印保存文件所使用的时间
        current_time = time.time()
        elapsed_time = current_time - prev_time
        print(f'Saved {csv_file_name} successfully. Elapsed time: {elapsed_time:.2f} seconds')
        prev_time = current_time

# 使用多线程处理Excel文件
with ThreadPoolExecutor(max_workers=16) as executor:  # 可根据需要设置最大线程数
    executor.map(process_excel, excel_files)

print('拆分完成!')
 楼主| heiyahua 发表于 2023-6-9 14:59
ifdess 发表于 2023-6-9 11:27
在处理较大的Excel文件时,可以尝试以下几个优化方法:

1. 逐步读取数据:使用`pd.read_excel`函数时, ...

多谢指导
 楼主| heiyahua 发表于 2023-6-9 15:44
longteng9421 发表于 2023-6-9 11:51
[mw_shl_code=python,true]import os
import pandas as pd
import logging

多谢修改!!
law.liu 发表于 2023-6-9 18:07
我在这里使用多线程提高速度的方法,但具体的性能提升取决于你电脑的配置和数据集的大小。
代码修改如下“”
[Python] 纯文本查看 复制代码
import os
import pandas as pd
import logging
import time
from concurrent.futures import ThreadPoolExecutor
import dask.dataframe as dd

# 获取当前文件夹路径
current_dir = os.getcwd()

# 获取当前文件夹内的所有Excel文件
excel_files = [file for file in os.listdir(current_dir) if file.endswith('.xlsx') or file.endswith('.xls')]

# 设置openpyxl日志级别为ERROR,忽略Workbook无默认样式的告警
logging.getLogger('openpyxl').setLevel(logging.ERROR)

# 设置pandas不输出警告信息
pd.options.mode.chained_assignment = None  # 取消chained_assignment警告
pd.options.mode.use_inf_as_na = True  # 将inf视为缺失值,避免警告输出

# 定义处理Excel文件的函数
def process_excel(excel_file):
    # 创建以Excel文件命名的文件夹
    excel_folder = os.path.splitext(excel_file)[0]
    if not os.path.exists(excel_folder):
        os.makedirs(excel_folder)

    # 读取Excel文件中的sheet名
    excel = pd.ExcelFile(excel_file)
    sheet_names = excel.sheet_names

    # 遍历每个sheet,将第三行及以下的内容保存为CSV文件
    for sheet_name in sheet_names:
        # 读取Excel文件中的每个sheet,选择需要读取的列
        df_sheet = pd.read_excel(excel_file, sheet_name=sheet_name, usecols=lambda x: x not in range(2), engine='openpyxl')

        # 将sheet名作为文件名,保存为CSV文件
        csv_file_name = os.path.join(excel_folder, f'{sheet_name}.csv')
        df_sheet.to_csv(csv_file_name, index=False, encoding='gbk')

        print(f'Saved {csv_file_name} successfully.')

# 使用多线程处理Excel文件
with ThreadPoolExecutor(max_workers=16) as executor:
    executor.map(process_excel, excel_files)

print('拆分完成!')
一闪一闪233 发表于 2023-6-10 03:39
[Python] 纯文本查看 复制代码
import os
import pandas as pd
import time
from concurrent.futures import ThreadPoolExecutor

# 获取当前文件夹路径
current_dir = os.getcwd()

# 获取当前文件夹内的所有Excel文件
excel_files = [file for file in os.listdir(current_dir) if file.endswith('.xlsx') or file.endswith('.xls')]

# 设置pandas不输出警告信息
pd.options.mode.chained_assignment = None  # 取消chained_assignment警告
pd.options.mode.use_inf_as_na = True  # 将inf视为缺失值,避免警告输出

# 定义处理Excel文件的函数
def process_excel_sheet(args):
    excel_file, sheet_name = args

    # 创建以Excel文件命名的文件夹
    excel_folder = os.path.splitext(excel_file)[0]
    if not os.path.exists(excel_folder):
        os.makedirs(excel_folder)

    # 读取Excel文件中的每个sheet,跳过前两行
    df_sheet = pd.read_excel(excel_file, sheet_name=sheet_name, skiprows=2, engine='openpyxl')

    # 将sheet名作为文件名,保存为CSV文件
    csv_file_name = os.path.join(excel_folder, f'{sheet_name}.csv')
    df_sheet.to_csv(csv_file_name, index=False, encoding='gbk')

    print(f'Saved {csv_file_name} successfully.')

# 创建处理任务列表
tasks = []

for excel_file in excel_files:
    # 读取Excel文件中的sheet名
    excel = pd.ExcelFile(excel_file)
    sheet_names = excel.sheet_names

    for sheet_name in sheet_names:
        tasks.append((excel_file, sheet_name))

# 使用多线程处理Excel文件中的每个sheet
with ThreadPoolExecutor(max_workers=16) as executor:  # 可根据需要设置最大线程数
    executor.map(process_excel_sheet, tasks)

print('拆分完成!')
zpy2 发表于 2023-6-10 07:13
golang excelize有个流式读取,可以试试
您需要登录后才可以回帖 登录 | 注册[Register]

本版积分规则

返回列表

RSS订阅|小黑屋|处罚记录|联系我们|吾爱破解 - LCG - LSG ( 京ICP备16042023号 | 京公网安备 11010502030087号 )

GMT+8, 2024-11-24 22:53

Powered by Discuz!

Copyright © 2001-2020, Tencent Cloud.

快速回复 返回顶部 返回列表