Python 的大文件解析

2023-11-01 18:48:51 +08:00
 jiminjohn0402
今天做了一个 3gcsv 数据量 2100 万条的 csv 拆分,因为 csv 总提示数据超长,然后就导出为 xlsx ,但是非常慢,因为是初次接触,是不是哪里有什么问题。但是如果只是拆分 csv 不会很慢(都会先按一个字段进行排序)。
想问下各位大佬对于这一类型的数据拆分和解析如何处理,有什么优化方案?用的是 mbp 19 16g 内存 intel i7
3018 次点击
所在节点    Python
18 条回复
l1xnan
2023-11-01 19:15:28 +08:00
没明白你那个“因为..., 然后 ...” 的因果关系。如果是读 csv 慢,用最新版本的 pandas 或者 pyarrow 或者 duckdb ,都非常快,不要自己写 open/for 循环,如果是写 xlsx 慢,格式决定写速度可优化空间不多,xlsxwriter 相比 openpyxl 性能好点,用 constant_memory=optimised 参数,内存优化非常明显,速度会比 openpyxl 库快一点
evemoo
2023-11-01 20:54:22 +08:00
一种思路
```python
def list_split(source_list, n):
return [source_list[i:i+n] for i in range(0, len(source_list), n)]

while line := f.readline():
do_something
```
orangie
2023-11-01 22:07:20 +08:00
感觉像是没用 pandas ,而是自己解析和处理 csv 。对于 pandas 来说 3GB 的文件不大。
NoOneNoBody
2023-11-02 04:05:23 +08:00
你这个需要汇总么?不需要的话,读一行处理一行,添加到相应文件
如果只是拆分,不需要计算的话,按这种方式纯文字处理很快的
SuperXX
2023-11-02 04:37:53 +08:00
拆分的闭着眼睛用 np.split
读写慢 用 parquet 或者 DuckDB , 其实这个数据量才 3GB….

楼主得好好提升一下自己的语文, 虽然不知道你到底要表达啥,我还是盲猜吧
ho121
2023-11-02 07:10:08 +08:00
不如试试 Access
bianhui
2023-11-02 08:13:03 +08:00
没看明白啥意思,如果导出 xlsx excel 直接另存为不就行了吗。如果解析数据,read line ,不要 read lines 。
hyperbin
2023-11-02 08:18:34 +08:00
excel 最多 1048576 行
missuo
2023-11-02 08:34:46 +08:00
用 readline ,不要用 readlines ,不就行了
jiminjohn0402
2023-11-02 08:39:40 +08:00
@l1xnan 确实说的有问题,是因为两个原因要拆分
1 、文件太大,单独打开太慢
2 、即便打开了提示字段超长,可能现实不全,但是转为 xlsx 不会有这个问题
然后就开始想拆分方案,我自己参考网上的方案写了一份,感觉有点慢:

import pandas as pd

# 读取 CSV 文件
data = pd.read_csv('customer.csv')

# 按照“客户编号”列排序
# 转换为字符串列排序
data['客户编号'] = data['客户编号'].astype('str')
sorted_data = data.sort_values(by='客户编号', ascending=False)

# 将数据拆分为 30 个数据桢并保存为 CSV 文件
num_files = 30
chunk_size = len(sorted_data) // num_files

for i in range(num_files):
start_idx = i * chunk_size
if i < num_files - 1:
end_idx = (i + 1) * chunk_size
else:
end_idx = len(sorted_data)

chunk = sorted_data.iloc[start_idx:end_idx]
chunk.to_excel(f'chunk_{i + 1}.xlsx', index=False)
laqow
2023-11-02 09:03:37 +08:00
直接 bash 下用 head -l 拆不就行了?拆完每个文件加上第一个文件的第一行,然后用 python 或什么别的多进程转成 excel 。
超过 10M 的文件都不要用 excel ,不然每次打开都要等半天,excel 还有各种自动转码的 feature ,长数字转 int 超长截断,反斜杠变日期之类的。reCSVEditor 之类的直接看 csv 要简单很多。
Maerd
2023-11-02 09:18:51 +08:00
xlsx 自带压缩,基础数据类型也和 csv 不同,你在转出时首先要将数据格式转成 xlsx 的格式,然后再进行压缩,你想想这能快吗
jiyan5
2023-11-02 11:29:07 +08:00
吐槽下 excel 的后缀名是啥玩意,不如 doc ppt 的好记
volvo007
2023-11-02 11:36:41 +08:00
@jiminjohn0402 有点慢是多慢?一般最新的 pandas 打开 3G 的 csv 应该和玩一样。如果慢,可能和你的数据类型有关,比如如果日期类比较多的话,pd 会用不同的日期格式去匹配,这个过程也是非常慢的。嫌慢也可以考虑基于 pyarrow 的 polars 去处理。arrow 是 Apache 的顶级框架之一,专门用来处理大数据的。此外,pd 是基于 numpy 的,而 numpy 本身不包含 string 类型,因为这不是 numpy 最关心的问题,它都是“数据”计算。所以如果文本类型比较多得话,还是考虑 pyarrow 这种原生支持 string 的库去处理才是合适的
djangovcps
2023-11-02 12:02:35 +08:00
众所周知 python 的各种库 写 excel 都是慢的,根本就没说到点子上,真的嫌慢,用 python3.11 有伪 jit 加速,写 xlsx 会快 80%,我试过的
jiminjohn0402
2023-11-02 13:13:07 +08:00
@volvo007 大概花了两个小时分拆出 30 个文件,每个文件 80 多万条数据
NoOneNoBody
2023-11-02 13:14:42 +08:00
@jiminjohn0402 #10
首先看你写的,并不需要 pandas ,逐条读取,提取客户编号作为判断,然后写到 xlsx ,加几个计数器的事,当然这样没有排序,但可以不同客户编号用不同输出

或者倒入 sqlite ,后面就不用说了

然后说这段代码
1.sort_values 应该加上 ignore_index=True ,重排 index
2.你这个完全可以用 groupby ,不用 sort ,2000w 条为了分编号 sort 没必要
3.有个 more_itertools.chunked ,不用自己算切片
4.也可以用 while + dataframe.head ,每次 drop 已完成的部分

看整个流程关键点是排序,而且你这个也仅仅是客户编号排序而已,如果这不是必须的,选择方式就很多了
volvo007
2023-11-02 16:15:03 +08:00
@jiminjohn0402 这个速度非常不正常,可能的话再多给一些数据结构的信息吧,或者直接上代码,做个列名的脱敏处理。30 个文件,每个才 100 M ,这种估计 2-5 分钟完成比较正常

这是一个专为移动设备优化的页面(即为了让你能够在 Google 搜索结果里秒开这个页面),如果你希望参与 V2EX 社区的讨论,你可以继续到 V2EX 上打开本讨论主题的完整版本。

https://www.v2ex.com/t/987605

V2EX 是创意工作者们的社区,是一个分享自己正在做的有趣事物、交流想法,可以遇见新朋友甚至新机会的地方。

V2EX is a community of developers, designers and creative people.

© 2021 V2EX