我正在使用numpy.delete从while循环内的数组中删除元素。 仅当数组不为空时,此while循环才有效。此代码工作正常但速度慢 当阵列有超过1e6个元素时。这是一个例子:
while(array.shape[0] > 0):
ix = where((array >= x) & (array <= y))[0]
array = delete(array,ix,None)
我试图使这段代码有效但我找不到加速while循环的好方法。我认为,这里的瓶颈是必须包含某种副本的删除。我已经尝试使用蒙面数组以避免复制,但我不擅长python和掩码数组不是那么容易搜索。有没有一种好的,快速的方法来使用删除或替换它,以便7e6元素可以通过上面的循环处理而不需要24小时?
由于
答案 0 :(得分:7)
因此,您可以通过以下方式大幅提高代码的性能:
消除循环;以及
避免删除操作(导致原件的副本 阵列)
NumPy 1.7推出了一款比原版更容易使用的新面膜;它的性能也好得多,因为它是 NumPy核心数组对象的一部分。我认为这可能对您有用,因为通过使用它,您可以 避免昂贵的删除操作 。
换句话说,不是删除你不想要的数组元素,而只是掩盖它们。这已在其他答案中提出,但我建议使用新面具
使用NA,只需导入NA
>>> from numpy import NA as NA
然后对于给定的数组,将maskna标志设置为 True
>>> A.flags.maskna = True
或者,大多数数组构造函数(从1.7开始)都有参数maskna,您可以将其设置为 True
>>> A[3,3] = NA
array([[7, 5, 4, 8, 4],
[2, 4, 3, 7, 3],
[3, 1, 3, 2, 1],
[8, 2, 0, NA, 7],
[0, 7, 2, 5, 5],
[5, 4, 2, 7, 4],
[1, 2, 9, 2, 3],
[7, 5, 1, 2, 9]])
>>> A.sum(axis=0)
array([33, 30, 24, NA, 36])
通常这不是您想要的 - 也就是说,您仍然希望将该列的总和与NA一起视为0:
要获得该行为,请传入 True 以获取skipma参数(大多数NumPy数组构造函数在NumPy 1.7中具有此参数):
>>> A.sum(axis=0, skipna=True)
array([33, 30, 24, 33, 36])
总而言之,为了加速你的代码,消除循环并使用新的掩码:
>>> A[(A<=3)&(A<=6)] = NA
>>> A
array([[8, 8, 4, NA, NA],
[7, 9, NA, NA, 8],
[NA, 6, 9, 5, NA],
[9, 4, 6, 6, 5],
[NA, 6, 8, NA, NA],
[8, 5, 7, 7, NA],
[NA, 4, 5, 9, 9],
[NA, 8, NA, 5, 9]])
NA占位符 - 在此上下文中 - 表现得像0,我相信这就是你想要的:
>>> A.sum(axis=0, skipna=True)
array([32, 50, 39, 32, 31])
答案 1 :(得分:3)
如果我错了,请纠正我,但我认为你可以这样做:
mask=np.where((array >= x) & (array <= y),True,False)
array=array[mask]
并放弃整个循环?
另外,在我的解释器中,array >= x & array <= y
会产生异常。你可能意味着:
(array >= x) & (array <= y)
答案 2 :(得分:2)
根据numpy.delete的文档,该函数返回输入数组的副本,其中删除了指定的元素。因此,您复制的数组越大,功能就越慢。
http://docs.scipy.org/doc/numpy/reference/generated/numpy.delete.html
为什么你需要经常删除数组的块?如果您的数组非常动态,那么最好使用list
来存储数组的各个部分,并且一次只能在较小的位上进行删除。