我是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
是指到整个数组。
如何使用屏蔽方法而不是循环来更正此代码?
答案 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])
因此mask
从a
的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.where
或numpy.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]