是我太菜了,还是 pandans 就是这么慢

2024-06-06 22:00:36 +08:00
 jianghu52

thinkpad T14 的机器,i7 的 cup ,32G 内存。 我有两个 excel ,一个 4 千行,6 列 名字叫 tb4k ,一个 6 千行,10 列,名字叫 tb6k 。 都用 pandas 接成 df 对象,然后循环两个 df 。最后保存成 excel 。

伪代码 遍历 tb4k 的每一行,取前三列的内容: 遍历 tb6k: tb6k 的前三列一致: 将 tb6k 的后面第 5,8,10 行的内容赋值给 tb4k 的后三列 停止遍历 tb6k 保存 tb4k 到原 excel

我执行段代码。tb4k 遍历每一行大概需要 1s 左右(包含 tb6k 的遍历)。导致我运行这段程序要接近 1 小时。 这速度也太慢了吧。还是我水平太菜了,没有用好 pandas ?

5024 次点击
所在节点    Python
41 条回复
shinonome
2024-06-06 22:40:42 +08:00
4 千还是 4 千万呢,感觉你这数据量基本上是几秒就结束的吧,

我还是怀疑代码问题

Python 虽然慢,那也是相对而言的,对人来说应该是没有明显感知的
yagamil
2024-06-06 23:04:00 +08:00
太菜。鉴定完毕。
xgdgsc
2024-06-06 23:13:52 +08:00
按行循环应该考虑用 julia , io 可以调 python 完成 https://github.com/JuliaPy/PythonCall.jl ,数据处理部分用 julia 无脑循环
jayeli
2024-06-07 01:36:48 +08:00
为什么不 merge 呢?
Lycnir
2024-06-07 09:04:15 +08:00
可以把代码发出来瞧瞧~
wang93wei
2024-06-07 09:07:34 +08:00
换成 polars 再试试,如果 polars 也慢说明你代码写的有问题。
hackhu2019
2024-06-07 09:07:58 +08:00
df 对象每次迭代生成的对象开销很大,多半是你迭代的方法不对可以看看这个 https://stackoverflow.com/questions/16476924/how-can-i-iterate-over-rows-in-a-pandas-dataframe
l1xnan
2024-06-07 09:12:35 +08:00
哪怕自己调 Excel 包写循环也不会这么慢吧,想起来那些 Python 新手声称遇到 Python BUG 在网上提问的
yy77
2024-06-07 09:20:59 +08:00
Excel 的处理本来就是比较慢的。如果格式不重要的话,转成 csv 再用 pandas 处理,速度能上一个数量级。
crackidz
2024-06-07 09:27:38 +08:00
你这速度明显是使用问题了...
1462326016
2024-06-07 10:30:52 +08:00
每次循环都要重新遍历六千次,不可能快吧。把六千行那个 excel 的前三列和需要的数据做成 dict ,直接遍历四千行的那个 get 一下 dict ,一次完事,复杂度 O(1)
算下来都不需要 pandas 吧,如果不会用 excel 读写相关库当我没说,好像好多人习惯用 pandas 读取 excel 。
我习惯用 openpyxl 之类的读取 excel
aka863
2024-06-07 10:52:20 +08:00
建议使用 pandas.DataFrame.set_index(),把 DataFrame 的前 3 列设置为 MultiIndex ,再使用 pandas.DataFrame.join()。
gauthier
2024-06-07 10:55:32 +08:00
你这数据量理论上应该是秒算完,就算是导出成 excel 也不会花太久。用 cProfile 看看时间耗费在哪了,找找有没有 pandas 自己的 api 调用
aka863
2024-06-07 10:57:54 +08:00
不建议用逐行遍历、比较的方法,
那样的话,还不如在循环中用 python 的字典数据。
sgld
2024-06-07 12:22:18 +08:00
大概率代码问题,问题描述其实没太看明白,但是 pandas 中逐行遍历是效率最低的一种做法。可以考虑能不能使用矢量化的方法替代,没有代码也不清楚。

stackoverflow 中有很多这方面的回答,可以去看看。
sgld
2024-06-07 12:30:26 +08:00
问题中提到 tb6k 后面第 5 8 10 行的内容赋值给 tb4k 后三列。这里是不是 5 8 10 列

打错了的话,就两个表格 join 一下(前面有回答提到了),然后使用索引取需要的列。

如果不是别无他法,遍历都是最次选,实在不行考虑 aplly 这些🤩
sgld
2024-06-07 12:31:09 +08:00
@sgld apply
G64q9J89mN5KSgmE
2024-06-07 12:33:13 +08:00
打了一堆又删了
你还是让 gpt 帮你写吧
ipwx
2024-06-07 12:38:33 +08:00
你代码呢?

首先,python 不能用 for loop 。

其次,pandas 稍微一点细节,性能差别就很大。比如

* .loc 或者直接索引比 .iloc 慢很多。
* .iteritems() 可能比 .itertuples() 慢。
* 不要按行取数据,因为 Pandas 是按列存的。你取出一行就有一行的临时对象。
ipwx
2024-06-07 12:39:46 +08:00
实践中我千万级别的数据处理,很多操作也就 10 秒。

每天 600 多万行的 1 分钟 A 股数据,按每只股票聚合成 5, 10, 15, 30 分钟也就 20 秒。

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

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

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

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

© 2021 V2EX