提高NumPy阵列上的操作性能

She*_*284 8 python numpy

我正在使用numpy.delete从while循环内的数组中删除元素.仅当数组不为空时,此while循环才有效.此代码工作正常,但当数组超过1e6元素时,速度会大大降低.这是一个例子:

while(array.shape[0] > 0):
     ix = where((array >= x) & (array <= y))[0]
     array = delete(array,ix,None)
Run Code Online (Sandbox Code Playgroud)

我试图使这个代码有效,但我找不到一个加速while循环的好方法.我认为,这里的瓶颈是必须包含某种副本的删除.我已经尝试使用蒙面数组以避免复制,但我不擅长python和掩码数组不是那么容易搜索.有没有一种好的,快速的方法来使用删除或替换它,以便7e6元素可以通过上面的循环处理而不需要24小时?

谢谢

dou*_*oug 7

因此,您可以通过以下方式大幅提高代码的性能:

  • 消除循环; 和

  • 避免删除操作(导致原始数组的副本)

NumPy 1.7推出了一款比原版更容易使用的新面膜; 它的性能也好得多,因为它是NumPy核心数组对象一部分.我认为这可能对您有用,因为通过使用它可以避免昂贵的删除操作.

换句话说,不是删除你不想要的数组元素,而只是掩盖它们.这已在其他答案中提出,但我建议使用新的面具

使用NA,只需导入NA

>>> from numpy import NA as NA
Run Code Online (Sandbox Code Playgroud)

然后对于给定的数组,将maskna标志设置为True

>>> A.flags.maskna = True
Run Code Online (Sandbox Code Playgroud)

或者,大多数数组构造函数(从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])
Run Code Online (Sandbox Code Playgroud)

通常这不是你想要的 - 也就是说,你仍然希望该列的总和与NA一样被视为0:

要获得该行为,请为skipma参数传入True(大多数NumPy数组构造函数在NumPy 1.7中具有此参数):

>>> A.sum(axis=0, skipna=True)
array([33, 30, 24, 33, 36])
Run Code Online (Sandbox Code Playgroud)

总而言之,为了加速代码,消除循环并使用新的掩码:

>>> 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]])
Run Code Online (Sandbox Code Playgroud)

NA占位符 - 在这种情况下 - 表现得像0,我相信你想要的:

>>> A.sum(axis=0, skipna=True)
array([32, 50, 39, 32, 31])
Run Code Online (Sandbox Code Playgroud)

  • `np.NA`的东西显然实际上并没有成为1.7. (3认同)