减少Python中长for循环的时间
我这边又有个傻问题 ;) 我在处理一个代码片段时遇到了一些问题,变量的长度都是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])
所有的变量都是浮点数或整数,除了 arr
和 grid
。arr
是一维数组,而 grid
是二维数组。
我的问题是,循环运行起来花了很长时间(几分钟)。有没有人能告诉我,为什么会这么慢?有没有什么建议?即使我试着把 range()
换成 arange()
,也只节省了几秒钟。
谢谢。
第一次编辑
抱歉,忘了说我在导入 numpy
。
第二次编辑
我在一个二维网格中有一些点。网格的每个单元格都有一个存储的值。我需要找出这些点的位置,并将值应用到一个新的数组中。这就是我的问题和想法。
附言:如果你想更好地理解,可以看看图片。单元格的值用不同的颜色表示。
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的列表来用,这样做效率会很低。