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