当前位置: 首页 > news >正文

利用pypy加速pyxlsbwriter生成xlsb文件

上文介绍了python通过DuckDB和pyxlsbwriter模块生成xlsb文件,因为python是解释执行,它的速度有点慢,pypy是另一种python解释器,它使用即时编译(JIT)技术来提高执行速度。
因为DuckDB与pypy不兼容,所以让DeepSeek帮助编写了不依赖DuckDB和pandas,直接使用python csv模块将csv文件内容写入多sheet的xlsb文件的程序。
源代码csv2xlsb.py如下:

import csv
import math
from pyxlsbwriter import XlsbWriterdef csv_to_xlsb(csv_file,output_file,sheet_prefix="Sheet",max_rows_per_sheet=1048575,  # XLSB 单 Sheet 最大行数compression_level=6,has_header=True
):"""将大型 CSV 文件分 Sheet 写入 XLSB 文件参数:csv_file (str): 输入 CSV 文件路径output_file (str): 输出 XLSB 文件路径sheet_prefix (str): Sheet 名称前缀max_rows_per_sheet (int): 每个 Sheet 最大行数compression_level (int): 压缩级别(0-9)has_header (bool): CSV 是否包含标题行"""# 首先计算总行数(为了确定需要的 Sheet 数量)with open(csv_file, 'r', newline='', encoding='utf-8') as f:total_rows = sum(1 for _ in csv.reader(f)) - (1 if has_header else 0)num_sheets = math.ceil(total_rows / max_rows_per_sheet)print(f"CSV 文件共有 {total_rows} 行数据,将分成 {num_sheets} 个 Sheet 写入")with XlsbWriter(output_file, compressionLevel=compression_level) as writer:with open(csv_file, 'r', newline='', encoding='utf-8') as f:csv_reader = csv.reader(f)# 读取标题行(如果有)headers = next(csv_reader) if has_header else Nonecurrent_sheet = 0current_row = 0sheet_data = []# 添加标题行到第一个 Sheetif headers:sheet_data.append(headers)for row in csv_reader:sheet_data.append(row)current_row += 1# 当达到最大行数时写入当前 Sheet 并创建新 Sheetif current_row >= max_rows_per_sheet:# 写入当前 Sheetsheet_name = f"{sheet_prefix}_{current_sheet + 1}"writer.add_sheet(sheet_name)writer.write_sheet(sheet_data)print(f"已写入 Sheet: {sheet_name},行数: {len(sheet_data)}")# 准备下一个 Sheetcurrent_sheet += 1current_row = 0sheet_data = []if headers:  # 新 Sheet 也包含标题行sheet_data.append(headers)# 写入最后一个 Sheet(可能未达到最大行数)if sheet_data:sheet_name = f"{sheet_prefix}_{current_sheet + 1}"writer.add_sheet(sheet_name)writer.write_sheet(sheet_data)print(f"已写入 Sheet: {sheet_name},行数: {len(sheet_data)}")if __name__ == "__main__":# 示例用法csv_to_xlsb(csv_file="5m Sales Records.csv",output_file="sheets.xlsb",sheet_prefix="Data",max_rows_per_sheet=1048575,  # 每个 Sheet 100 万行compression_level=6,has_header=True)

下面是在pypy中安装pyxlsbwriter并执行的步骤

C:\d\pypy>pypy3 -m ensurepip
Successfully installed pip-24.0 setuptools-65.5.0C:\d\pypy>pypy3 -m pip install pyxlsbwriter
Successfully installed pyxlsbwriter-0.0.3C:\d\pypy>cd ..C:\d>timer64 pypy\pypy3 csv2xlsb.pyKernel  Time =     1.750 =    2%
User    Time =    58.546 =   97%
Process Time =    60.296 =  100%    Virtual  Memory =   3858 MB
Global  Time =    60.271 =  100%    Physical Memory =   3828 MB

我把第一步生成的sheets.xlsb文件改名为pypysheets.xlsb,以便比较。再用python执行同样的代码。

C:\d>move sheets.xlsb pypysheets.xlsb
移动了         1 个文件。C:\d>timer64 python csv2xlsb.py
CSV 文件共有 5000000 行数据,将分成 5 个 Sheet 写入
已写入 Sheet: Data_1,行数: 1048576
已写入 Sheet: Data_2,行数: 1048576
已写入 Sheet: Data_3,行数: 1048576
已写入 Sheet: Data_4,行数: 1048576
已写入 Sheet: Data_5,行数: 805701Kernel  Time =     1.640 =    1%
User    Time =    85.218 =   97%
Process Time =    86.859 =   99%    Virtual  Memory =   4728 MB
Global  Time =    87.267 =  100%    Physical Memory =   4724 MB

可见pypy3执行时间比python缩短了三分之一。再比较两个生成的文件,大小完全一致,再用FC命令比较,发现还是存在差异的。

C:\d>dir *sheets.xlsb2025/08/17  18:32       201,303,180 pypysheets.xlsb
2025/08/17  18:34       201,303,180 sheets.xlsbC:\d>fc /b sheets.xlsb pypysheets.xlsb
正在比较文件 sheets.xlsb 和 PYPYSHEETS.XLSB
024E15D8: 37 F5
024E15D9: 94 93
024E16D0: 37 F5
024E16D1: 94 93
...
0BFFA380: 57 0A
0BFFA3BD: 57 0A
0BFFA3F8: 57 0A

那pypy生成的文件到底对不对,能不能用,还是用rust_sheet插件来读取,比较如下:
先读取用python生成的sheets.xlsb

D create table xlsb as from read_sheet('sheets.xlsb',header=1,sheet_name='Data_1')
union all from read_sheet('sheets.xlsb',header=1,sheet_name='Data_2')
union all from read_sheet('sheets.xlsb',header=1,sheet_name='Data_3')
union all from read_sheet('sheets.xlsb',header=1,sheet_name='Data_4')
union all from read_sheet('sheets.xlsb',header=1,sheet_name='Data_5');
100% ▕████████████████████████████████████████████████████████████▏
Run Time (s): real 47.218 user 52.890625 sys 2.437500
D summarize xlsb;
┌────────────────┬─────────────┬─────────────┬────────────────────┬───┬───────┬───────┬─────────┬─────────────────┐
│  column_name   │ column_type │     min     │        max         │ … │  q50  │  q75  │  count  │ null_percentage │
│    varcharvarcharvarcharvarchar       │   │ int32 │ int32 │  int64  │  decimal(9,2)   │
├────────────────┼─────────────┼─────────────┼────────────────────┼───┼───────┼───────┼─────────┼─────────────────┤
│ Region         │ VARCHAR     │ Asia        │ Sub-Saharan Africa │ … │  NULLNULL50000000.00 │
│ Country        │ VARCHAR     │ Afghanistan │ Zimbabwe           │ … │  NULLNULL50000000.00 │
│ Item TypeVARCHAR     │ Baby Food   │ Vegetables         │ … │  NULLNULL50000000.00 │
│ Sales Channel  │ VARCHAR     │ Offline     │ Online             │ … │  NULLNULL50000000.00 │
│ Order Priority │ VARCHAR     │ C           │ M                  │ … │  NULLNULL50000000.00 │
│ Order DateVARCHAR1/1/20109/9/2020           │ … │  NULLNULL50000000.00 │
│ Order ID       │ VARCHAR100000321999999892          │ … │  NULLNULL50000000.00 │
│ Ship DateVARCHAR1/1/20109/9/2020           │ … │  NULLNULL50000000.00 │
│ Units Sold     │ VARCHAR19999               │ … │  NULLNULL50000000.00 │
│ Unit Price     │ VARCHAR109.289.33               │ … │  NULLNULL50000000.00 │
│ Unit Cost      │ VARCHAR117.1197.44              │ … │  NULLNULL50000000.00 │
│ Total Revenue  │ VARCHAR1000003.46999931.76          │ … │  NULLNULL50000000.00 │
│ Total Cost     │ VARCHAR1000.23999979.98          │ … │  NULLNULL50000000.00 │
│ Total Profit   │ VARCHAR100.2499997.92           │ … │  NULLNULL50000000.00 │
├────────────────┴─────────────┴─────────────┴────────────────────┴───┴───────┴───────┴─────────┴─────────────────┤
│ 14 rows                                                                                    12 columns (8 shown) │
└─────────────────────────────────────────────────────────────────────────────────────────────────────────────────┘
Run Time (s): real 0.238 user 2.031250 sys 0.140625

再读取用pypy生成, 改名后的pypysheets.xlsb

D create table xlsb as from read_sheet('pypysheets.xlsb',header=1,sheet_name='Data_1')
union all from read_sheet('pypysheets.xlsb',header=1,sheet_name='Data_2')
union all from read_sheet('pypysheets.xlsb',header=1,sheet_name='Data_3')
union all from read_sheet('pypysheets.xlsb',header=1,sheet_name='Data_4')
union all from read_sheet('pypysheets.xlsb',header=1,sheet_name='Data_5');
100% ▕████████████████████████████████████████████████████████████▏
Run Time (s): real 45.734 user 43.078125 sys 2.531250
D summarize xlsb;
┌────────────────┬─────────────┬─────────────┬────────────────────┬───┬───────┬───────┬─────────┬─────────────────┐
│  column_name   │ column_type │     min     │        max         │ … │  q50  │  q75  │  count  │ null_percentage │
│    varcharvarcharvarcharvarchar       │   │ int32 │ int32 │  int64  │  decimal(9,2)   │
├────────────────┼─────────────┼─────────────┼────────────────────┼───┼───────┼───────┼─────────┼─────────────────┤
│ Region         │ VARCHAR     │ Asia        │ Sub-Saharan Africa │ … │  NULLNULL50000000.00 │
│ Country        │ VARCHAR     │ Afghanistan │ Zimbabwe           │ … │  NULLNULL50000000.00 │
│ Item TypeVARCHAR     │ Baby Food   │ Vegetables         │ … │  NULLNULL50000000.00 │
│ Sales Channel  │ VARCHAR     │ Offline     │ Online             │ … │  NULLNULL50000000.00 │
│ Order Priority │ VARCHAR     │ C           │ M                  │ … │  NULLNULL50000000.00 │
│ Order DateVARCHAR1/1/20109/9/2020           │ … │  NULLNULL50000000.00 │
│ Order ID       │ VARCHAR100000321999999892          │ … │  NULLNULL50000000.00 │
│ Ship DateVARCHAR1/1/20109/9/2020           │ … │  NULLNULL50000000.00 │
│ Units Sold     │ VARCHAR19999               │ … │  NULLNULL50000000.00 │
│ Unit Price     │ VARCHAR109.289.33               │ … │  NULLNULL50000000.00 │
│ Unit Cost      │ VARCHAR117.1197.44              │ … │  NULLNULL50000000.00 │
│ Total Revenue  │ VARCHAR1000003.46999931.76          │ … │  NULLNULL50000000.00 │
│ Total Cost     │ VARCHAR1000.23999979.98          │ … │  NULLNULL50000000.00 │
│ Total Profit   │ VARCHAR100.2499997.92           │ … │  NULLNULL50000000.00 │
├────────────────┴─────────────┴─────────────┴────────────────────┴───┴───────┴───────┴─────────┴─────────────────┤
│ 14 rows                                                                                    12 columns (8 shown) │
└─────────────────────────────────────────────────────────────────────────────────────────────────────────────────┘
Run Time (s): real 0.240 user 1.843750 sys 0.343750

读取时间基本一致,内容也一致。
所以,可以放心利用pypy加速pyxlsbwriter生成xlsb文件。

http://www.dtcms.com/a/336658.html

相关文章:

  • 五、redis入门 之 客户端连接redis
  • 日语学习-日语知识点小记-进阶-JLPT-N1阶段蓝宝书,共120语法(3):21-30语法
  • 雷卯针对香橙派Orange Pi Kunpeng Pro开发板防雷防静电方案
  • CloudBeaver:基于浏览器的DBeaver
  • 机器学习案例——对好评和差评进行预测
  • 当AI替我“搬砖”,我的价值是什么?
  • 21.AlexNet
  • 金山办公的服务端开发工程师-25届春招部分笔试题
  • C# Newtonsoft.Json 反序列化子类数据丢失问题
  • DBeaver连接MySQL 8报错连接丢失
  • HTTP协议-3-HTTP/2是如何维持长连接的?
  • JAVA后端开发——Token自动续期机制的必要性
  • 【Linux内核】Linux信号机制
  • 【Linux】五种IO模型
  • JVM学习笔记-----StringTable
  • react 错误边界
  • Python 内置模块 collections 常用工具
  • 【撸靶笔记】第二关:GET -Error based -Intiger based
  • Spring Framework :IoC 容器的原理与实践
  • CW32L011_电机驱动器开发板试用
  • 工作中使用到的时序指标异常检测算法 TRPS 【Temporal Residual Pattern Similarity】和 K-sigma 算法
  • 区块链:数字时代信任基石的构建与创新
  • 25年第十本【金钱心理学】
  • 1. Docker的介绍和安装
  • 洛谷 P2324 [SCOI2005] 骑士精神-提高+/省选-
  • CE桥接MuMu模拟器
  • 计算机网络 Session 劫持 原理和防御措施
  • IC验证 AHB-RAM 项目(一)——项目理解
  • 【leetcode】58. 最后一个单词的长度
  • Python大模型应用开发-核心技术与项目开发