减少Python中长for循环的时间

1 投票
5 回答
2383 浏览
提问于 2025-04-16 15:41

我这边又有个傻问题 ;) 我在处理一个代码片段时遇到了一些问题,变量的长度都是7'700'000:

from numpy import *

for k in range(len(x)):
    if x[k] == xmax:
        xind = -1
    else:
        xind = int(floor((x[k]-xmin)/xdelta))
    if y[k] == ymax:
        yind = -1
    else:
        yind = int(floor((y[k]-ymin)/ydelta))

    arr = append(arr,grid[xind,yind])

所有的变量都是浮点数或整数,除了 arrgridarr 是一维数组,而 grid 是二维数组。

我的问题是,循环运行起来花了很长时间(几分钟)。有没有人能告诉我,为什么会这么慢?有没有什么建议?即使我试着把 range() 换成 arange(),也只节省了几秒钟。

谢谢。

第一次编辑

抱歉,忘了说我在导入 numpy

第二次编辑

我在一个二维网格中有一些点。网格的每个单元格都有一个存储的值。我需要找出这些点的位置,并将值应用到一个新的数组中。这就是我的问题和想法。

附言:如果你想更好地理解,可以看看图片。单元格的值用不同的颜色表示。

idea

5 个回答

0

我怀疑问题可能出在你存储结果的方式上:

arr = append(arr,grid[xind,yind])

关于append的文档说,它返回的是:

一个新的数组,里面包含了原数组arr和添加的values,并且是在axis这个方向上添加的。注意,append并不是在原地操作的:它会分配一个新的数组并填充数据。

这意味着在每次循环中,你都会不断地释放和分配一个越来越大的数组。我建议你提前分配一个合适大小的数组,然后在每次循环中把数据填进去。例如:

arr = empty(len(x))

for k in range(len(x)):
    ...
    arr[k] = grid[xind,yind]
1
for x_item, y_item in zip(x, y):
    # do stuff.

如果你不想生成一个特别大的额外列表,还有一个叫做 izip 的东西可以用。

4

你可以试试这样的写法:

import numpy as np
xind = np.floor((x-xmin)/xdelta).astype(int)
yind = np.floor((y-ymin)/ydelta).astype(int)

xind[np.argmax(x)] = -1
yind[np.argmax(y)] = -1

arr = grid[xind,yind]

注意:如果你在使用numpy,别把数组当成Python的列表来用,这样做效率会很低。

撰写回答