我正在尝试使用过滤器来解决布尔错误
我使用了一个过滤器数组来解决迭代数组的布尔问题。它只适用于一个简单的列表,但是当它仅用于从数组中获取大于零的数字时,它再次显示错误。填充数组的方法是从标准正态分布中提取样本。
arr2 = np.array(list(filter(lambda x:x>0,rand_num)))
arr2
<ipython-input-80-af65f7c09d82> in <module>
1 rand_num = np.random.randn(5,5)
----> 2 arr2 = np.array(list(filter(lambda x:x>0,rand_num)))
3 arr2
ValueError: The truth value of an array with more than one element is ambiguous. Use a.any() or a.all()
答案 0 :(得分:3)
就像rand_num
是多维数组。在这种情况下,元素(所以x
)也将是一个数组。对于x > 0
,这是bool
的数组,但是不能说布尔数组是True
或False
。假设一个数组包含两个True
和三个False
。您是否考虑True
?
在这里可能不需要使用filter(..)
。您可以通过使用布尔数组下标来轻松过滤数组:
arr2 = rand_num[rand_num > 0]
例如:
>>> rand_num[rand_num > 0]
array([1, 1, 1, 1, 2, 1, 1, 1, 1, 1, 1])
或者,如果我们想保留形状,可以构造一个蒙版数组:
arr2 = np.ma.masked_array(rand_num, mask=rand_num <= 0)
这将产生:
>>> np.ma.masked_array(rand_num, mask=rand_num <= 0)
masked_array(
data=[[--, 1, 1, --, --],
[--, --, 1, --, --],
[--, 1, 2, --, --],
[--, --, --, 1, --],
[1, 1, 1, 1, 1]],
mask=[[ True, False, False, True, True],
[ True, True, False, True, True],
[ True, False, False, True, True],
[ True, True, True, False, True],
[False, False, False, False, False]],
fill_value=999999)
答案 1 :(得分:1)
您已经创建了一个二维浮点数组:
In [60]: rand_num = np.random.randn(5,5)
In [61]: rand_num
Out[61]:
array([[ 1.89811694, 0.44414858, -2.52994217, -0.17974148, -0.91167712],
[ 0.06534556, 0.04677172, -0.81580021, 0.08053772, -0.55459303],
[ 0.41316473, -0.35859064, 1.28860476, -0.22666389, 0.97562048],
[ 0.29465373, 0.71143579, -0.55552921, 0.37660919, 0.31482962],
[ 0.2768353 , -1.32999438, 0.0594767 , 1.50255302, 0.08658897]])
我们可以使用布尔掩码选择> 0的值:
In [62]: rand_num>0
Out[62]:
array([[ True, True, False, False, False],
[ True, True, False, True, False],
[ True, False, True, False, True],
[ True, True, False, True, True],
[ True, False, True, True, True]])
In [63]: rand_num[rand_num>0]
Out[63]:
array([1.89811694, 0.44414858, 0.06534556, 0.04677172, 0.08053772,
0.41316473, 1.28860476, 0.97562048, 0.29465373, 0.71143579,
0.37660919, 0.31482962, 0.2768353 , 0.0594767 , 1.50255302,
0.08658897])
对数组进行布尔索引会生成一个1d数组-因为每一行的True值数量都可以变化。
filter
像map
一样在数组的第一维上迭代:
In [64]: list(map(lambda x:x>0, rand_num))
Out[64]:
[array([ True, True, False, False, False]),
array([ True, True, False, True, False]),
array([ True, False, True, False, True]),
array([ True, True, False, True, True]),
array([ True, False, True, True, True])]
列表理解形式中的相同内容:
In [65]: [x>0 for x in rand_num]
Out[65]:
[array([ True, True, False, False, False]),
array([ True, True, False, True, False]),
array([ True, False, True, False, True]),
array([ True, True, False, True, True]),
array([ True, False, True, True, True])]
请注意,迭代的每个元素如何是形状为(5,)的numpy数组。这就是filter
令人窒息的地方。它需要一个简单的True / False布尔值,而不是数组。 Python if
和or
有相同的问题。 (实际上,我认为是numpy
拒绝将多项目数组传递给期望标量的Python函数,而引发了这种歧义错误。)
您可以将filter
应用于rand_num
的每一行:
In [66]: [list(filter(lambda x: x>0, row)) for row in rand_num]
Out[66]:
[[1.898116938827415, 0.4441485849428062],
[0.06534556093009064, 0.04677172433407727, 0.08053772013844711],
[0.41316473050686314, 1.2886047644946972, 0.9756204798856322],
[0.2946537313273924,
0.711435791237748,
0.3766091899348284,
0.31482961532956577],
[0.27683530300005493,
0.05947670354791034,
1.502553021817318,
0.0865889738396504]]
这些数字与Out[63]
中的数字相同,但按行划分-每个项中的项数不同。
@Willem Van Onsem的遮罩数组格式中的相同内容:
In [69]: np.ma.masked_array(rand_num, mask=rand_num <= 0)
Out[69]:
masked_array(
data=[[1.898116938827415, 0.4441485849428062, --, --, --],
[0.06534556093009064, 0.04677172433407727, --,
0.08053772013844711, --],
[0.41316473050686314, --, 1.2886047644946972, --,
0.9756204798856322],
[0.2946537313273924, 0.711435791237748, --, 0.3766091899348284,
0.31482961532956577],
[0.27683530300005493, --, 0.05947670354791034, 1.502553021817318,
0.0865889738396504]],
mask=[[False, False, True, True, True],
[False, False, True, False, True],
[False, True, False, True, False],
[False, False, True, False, False],
[False, True, False, False, False]],
fill_value=1e+20)