带有遮罩的numpy分配

时间:2019-02-08 22:03:11

标签: python numpy

我是Python的新手。在练习中,我应该使用掩码将以下列表中所有低于100的值乘以2:

a = np.array([230, 10, 284, 39, 76])

所以我写了以下代码:

import numpy as np
a = np.array([230, 10, 284, 39, 76])
cut = 100
a[a < cut] = a*2    

这将导致以下错误:
IndexError:索引230超出了大小为5的轴0的范围

这令人困惑,因为据我所知,a中的[a < cut]实际上是指数组a中的每个值,而a中的a*2是指到整个数组。

如何使用屏蔽方法而不是循环来更正此代码?

4 个答案:

答案 0 :(得分:1)

如果要分配给a < cut持有的地方(a < cut = [0, 1, 0, 1, 1]是布尔索引),则不确定要什么,当您分配给a[a < cut]时,您分配给放置元素为1的位置,这意味着在右侧它需要一个大小为3(当然是一个数字)的numpy数组。您可以做到

In [1]: a = np.array([230, 10, 284, 39, 76])

In [2]: a[a < cut] = 999

In [3]: a
Out[3]: array([230, 999, 284, 999, 999])

In [1]: a = np.array([230, 10, 284, 39, 76])

In [2]: a[a < cut] = a[a < cut] * 2

In [3]: a
Out[3]: array([230,  20, 284,  78, 152])

将所选元素乘以2。

答案 1 :(得分:0)

几乎正确了;

a[a < cut] *= 2

它将在原地执行操作,您将整个a数组乘以2并尝试将其“放入”一个<剪切空间(不可能,因为numpy创建后具有固定大小的数组) 。

答案 2 :(得分:0)

您的错误似乎是由a[a]而非a[a<cut]产生的:

In [508]: a[a]
---------------------------------------------------------------------------
IndexError                                Traceback (most recent call last)
<ipython-input-508-bcb5f2cb8e92> in <module>()
----> 1 a[a]

IndexError: index 230 is out of bounds for axis 1 with size 5

但是要查看预期的任务:

In [497]: a = np.array([230, 10, 284, 39, 76])
In [498]: mask = a<100
In [499]: mask
Out[499]: array([False,  True, False,  True,  True])

因此maska的5个元素中选择3个:

In [500]: a[mask]
Out[500]: array([10, 39, 76])

a*2乘以a的所有元素,生成5个元素的数组

In [501]: a*2
Out[501]: array([460,  20, 568,  78, 152])

将两者匹配必然会导致某种错误;我得到:

In [502]: a[mask] = a*2
---------------------------------------------------------------------------
ValueError                                Traceback (most recent call last)
<ipython-input-502-3df3d7d2d307> in <module>()
----> 1 a[mask] = a*2

ValueError: NumPy boolean array indexing assignment cannot assign 5 input values to the 3 output values where the mask is true

但是如果我也将面膜也涂在右侧:

In [503]: a[mask] = a[mask]*2
In [504]: a
Out[504]: array([230,  20, 284,  78, 152])

但是* =使就地乘法更加容易。

In [506]: a[mask] *= 2

答案 3 :(得分:0)

或者,定义了掩码之后,您可以使用numpy.wherenumpy.putmask

import numpy as np

a = np.array([230, 10, 284, 39, 76])
cut = 100
mask = a < cut # defines the mask

第一个不会更改原始数组:

res = np.where(mask, a*2,a)
a #=> [230  10 284  39  76]
res #=> [230  20 284  78 152]

第二个修改原始数组:

np.putmask(a, mask, a*2)
a #=> [230  20 284  78 152]