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

163 天前
 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 ?

4215 次点击
所在节点    Python
41 条回复
ipwx
162 天前
说错了 100 多万行的 1 分钟数据。
Sawyerhou
162 天前
加 3 个辅助列 tb6k shift -5,-8,-10 ,将 tb4k 和 tb6k 的前 3 列设为 multiIndex ,然后 loc 拼接。
目测你这个前三列应该没重复的,如果有,如楼上说用 join 替代 loc 。

不要循环,用矩阵运算,1s 都用不了。
datou06415
162 天前
6 千行的数据的话,以你的机器配置,直接用 DataFrame 的 read_excel() 把 excel 数据读进来再处理都行,避免一行行的读文件。如果文件非常多行,再考虑分批次处理。

想知道运行慢的具体原因,上 cProfile ,或者粗暴点,日志记录关键操作位置的起始时间。总之,性能调优,先上工具测量指标。
cogitoxin
162 天前
polars 你值得拥有
Rorysky
162 天前
都放内存里,哪儿来这么多的时间
jZEdn7k4
162 天前
这个速度真是你代码太菜的问题。。。
dbak
162 天前
pandas 有矢量化操作矩阵数据 你小子用的 for 循环吧
zealotxxxx
162 天前
只能说是太菜,如果不是学习,你的需求建议用 excel

另外,你 tb4k 直接走 df.loc 或者 ilock 都行,如果你用 loop 也只需要执行 4k 次。

但是你如果数据唯一,完全可以走 join ,然后直接取要拿的列就行了
zealotxxxx
162 天前
你不会是嵌套 loop 吧?

4000 * 6000 = 2400 万次? 那不慢才怪
psyer
162 天前
看下代码呢
weidaizi
162 天前
看了一下,这慢很正常呀,帮大家格式化一下楼主的伪代码:
```
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) 了
weidaizi
162 天前
@weidaizi = = 我晕,前面的空格没了
encro
162 天前
我用 pandas 计算 k 线指标,1 万跟 k 线,几十个指标也只要几秒钟。估计你用的 pandans 和我用的 pandas 不是一个东西。
billbur
162 天前
djangovcps
162 天前
感觉你笛卡尔积的循环了,要不嗯循环几千行不肯能一小时
kingbill
162 天前
我觉得是 T14 的锅,是 U 结尾的 i7 吗?
stiangao
162 天前
前三列一样就合并一行的内容吧,

按你的思路要遍历 4000*6000=2400w 次,那确实慢,

按这个方法写,遍历一次 6000 行,前三列拼一个 key, 后三列拼 value ,生成一个 dict,
遍历 4000 行的文件,从 dict 里查, 查到了就拼接,
总共遍历数据 1w 次
winglight2016
162 天前
太菜了,pandas 用成了 array

另外,两个单词都拼错了,看着难受┑( ̄Д  ̄)┍
henix
162 天前
遍历 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 ,算法跟你现在的保持不变,说不定都比你现在的方式快。
Laysan
162 天前
show your code

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

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

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

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

© 2021 V2EX