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 ?
1
shinonome 167 天前
4 千还是 4 千万呢,感觉你这数据量基本上是几秒就结束的吧,
我还是怀疑代码问题 Python 虽然慢,那也是相对而言的,对人来说应该是没有明显感知的 |
2
yagamil 167 天前 3
太菜。鉴定完毕。
|
3
xgdgsc 167 天前
按行循环应该考虑用 julia , io 可以调 python 完成 https://github.com/JuliaPy/PythonCall.jl ,数据处理部分用 julia 无脑循环
|
4
jayeli 167 天前
为什么不 merge 呢?
|
5
Lycnir 167 天前
可以把代码发出来瞧瞧~
|
6
wang93wei 167 天前 1
换成 polars 再试试,如果 polars 也慢说明你代码写的有问题。
|
7
hackhu2019 167 天前 1
df 对象每次迭代生成的对象开销很大,多半是你迭代的方法不对可以看看这个 https://stackoverflow.com/questions/16476924/how-can-i-iterate-over-rows-in-a-pandas-dataframe
|
8
l1xnan 167 天前
哪怕自己调 Excel 包写循环也不会这么慢吧,想起来那些 Python 新手声称遇到 Python BUG 在网上提问的
|
9
yy77 167 天前 1
Excel 的处理本来就是比较慢的。如果格式不重要的话,转成 csv 再用 pandas 处理,速度能上一个数量级。
|
10
crackidz 167 天前
你这速度明显是使用问题了...
|
11
1462326016 167 天前
每次循环都要重新遍历六千次,不可能快吧。把六千行那个 excel 的前三列和需要的数据做成 dict ,直接遍历四千行的那个 get 一下 dict ,一次完事,复杂度 O(1)
算下来都不需要 pandas 吧,如果不会用 excel 读写相关库当我没说,好像好多人习惯用 pandas 读取 excel 。 我习惯用 openpyxl 之类的读取 excel |
12
aka863 167 天前
建议使用 pandas.DataFrame.set_index(),把 DataFrame 的前 3 列设置为 MultiIndex ,再使用 pandas.DataFrame.join()。
|
13
gauthier 167 天前
你这数据量理论上应该是秒算完,就算是导出成 excel 也不会花太久。用 cProfile 看看时间耗费在哪了,找找有没有 pandas 自己的 api 调用
|
14
aka863 167 天前
不建议用逐行遍历、比较的方法,
那样的话,还不如在循环中用 python 的字典数据。 |
15
sgld 167 天前 via Android
大概率代码问题,问题描述其实没太看明白,但是 pandas 中逐行遍历是效率最低的一种做法。可以考虑能不能使用矢量化的方法替代,没有代码也不清楚。
stackoverflow 中有很多这方面的回答,可以去看看。 |
16
sgld 167 天前 via Android
问题中提到 tb6k 后面第 5 8 10 行的内容赋值给 tb4k 后三列。这里是不是 5 8 10 列
打错了的话,就两个表格 join 一下(前面有回答提到了),然后使用索引取需要的列。 如果不是别无他法,遍历都是最次选,实在不行考虑 aplly 这些🤩 |
18
ddkk1112 167 天前 1
打了一堆又删了
你还是让 gpt 帮你写吧 |
19
ipwx 167 天前 1
你代码呢?
首先,python 不能用 for loop 。 其次,pandas 稍微一点细节,性能差别就很大。比如 * .loc 或者直接索引比 .iloc 慢很多。 * .iteritems() 可能比 .itertuples() 慢。 * 不要按行取数据,因为 Pandas 是按列存的。你取出一行就有一行的临时对象。 |
20
ipwx 167 天前
实践中我千万级别的数据处理,很多操作也就 10 秒。
每天 600 多万行的 1 分钟 A 股数据,按每只股票聚合成 5, 10, 15, 30 分钟也就 20 秒。 |
21
ipwx 167 天前
说错了 100 多万行的 1 分钟数据。
|
22
Sawyerhou 167 天前 1
加 3 个辅助列 tb6k shift -5,-8,-10 ,将 tb4k 和 tb6k 的前 3 列设为 multiIndex ,然后 loc 拼接。
目测你这个前三列应该没重复的,如果有,如楼上说用 join 替代 loc 。 不要循环,用矩阵运算,1s 都用不了。 |
23
datou06415 167 天前
6 千行的数据的话,以你的机器配置,直接用 DataFrame 的 read_excel() 把 excel 数据读进来再处理都行,避免一行行的读文件。如果文件非常多行,再考虑分批次处理。
想知道运行慢的具体原因,上 cProfile ,或者粗暴点,日志记录关键操作位置的起始时间。总之,性能调优,先上工具测量指标。 |
24
cogitoxin 167 天前
polars 你值得拥有
|
25
Rorysky 167 天前
都放内存里,哪儿来这么多的时间
|
26
jZEdn7k4 167 天前
这个速度真是你代码太菜的问题。。。
|
27
dbak 167 天前
pandas 有矢量化操作矩阵数据 你小子用的 for 循环吧
|
28
zealotxxxx 167 天前
只能说是太菜,如果不是学习,你的需求建议用 excel
另外,你 tb4k 直接走 df.loc 或者 ilock 都行,如果你用 loop 也只需要执行 4k 次。 但是你如果数据唯一,完全可以走 join ,然后直接取要拿的列就行了 |
29
zealotxxxx 167 天前
你不会是嵌套 loop 吧?
4000 * 6000 = 2400 万次? 那不慢才怪 |
30
psyer 167 天前 via Android
看下代码呢
|
31
weidaizi 167 天前
看了一下,这慢很正常呀,帮大家格式化一下楼主的伪代码:
``` for _, row_tb4k in df_tb4k.iterrows(): for _, row_tb6k in df_tb6k.iterrows(): if row_tb4k["c1"] == row_tb6k["c1"] and row_tb4k["c2"] == row_tb6k["c2"] and row_tb4k["c3"] == row_tb6k["c3"]: row_tb4k["c4“] = row_tb6k["c5"] row_tb4k["c5“] = row_tb6k["c8"] row_tb4k["c6“] = row_tb6k["c10"] ``` * 首先,都用了 pandas 了,为啥手动遍历来合并? * 其次,即使徒手写,也需要建个索引来做呀,你这时间复杂度是 O(n^2) 了 |
33
encro 167 天前
我用 pandas 计算 k 线指标,1 万跟 k 线,几十个指标也只要几秒钟。估计你用的 pandans 和我用的 pandas 不是一个东西。
|
34
billbur 167 天前
|
35
djangovcps 167 天前
感觉你笛卡尔积的循环了,要不嗯循环几千行不肯能一小时
|
36
kingbill 167 天前
我觉得是 T14 的锅,是 U 结尾的 i7 吗?
|
37
stiangao 167 天前
前三列一样就合并一行的内容吧,
按你的思路要遍历 4000*6000=2400w 次,那确实慢, 按这个方法写,遍历一次 6000 行,前三列拼一个 key, 后三列拼 value ,生成一个 dict, 遍历 4000 行的文件,从 dict 里查, 查到了就拼接, 总共遍历数据 1w 次 |
38
winglight2016 167 天前
太菜了,pandas 用成了 array
另外,两个单词都拼错了,看着难受┑( ̄Д  ̄)┍ |
39
henix 167 天前 1
遍历 6000 行的 df 需要 1s 也太慢。你用没用 df.iterrows 遍历? iterrows 跟整数索引( for i in range(len(df)))的性能差别挺大的。
一点建议:为啥非要用 excel 和 pandas ?因为 excel 不是文本格式,不方便程序处理。pandas 个人认为对初学者来说有很多坑。 一个架构上的建议:先将你这两个 excel 另存为 csv 格式,然后用 Python 自带的 https://docs.python.org/zh-cn/3/library/csv.html 把每个文件读进来存成一个 list ,算法跟你现在的保持不变,说不定都比你现在的方式快。 |
40
Laysan 166 天前
show your code
|
41
usiantein 166 天前
talk is annoying, show your code
|