如何使用过滤器功能修复数组布尔错误

时间:2019-09-01 18:49:33

标签: python arrays numpy

我正在尝试使用过滤器来解决布尔错误

我使用了一个过滤器数组来解决迭代数组的布尔问题。它只适用于一个简单的列表,但是当它仅用于从数组中获取大于零的数字时,它再次显示错误。填充数组的方法是从标准正态分布中提取样本。

   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()

2 个答案:

答案 0 :(得分:3)

就像rand_num是多维数组。在这种情况下,元素(所以x)也将是一个数组。对于x > 0,这是bool的数组,但是不能说布尔数组是TrueFalse。假设一个数组包含两个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值数量都可以变化。

filtermap一样在数组的第一维上迭代:

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 ifor有相同的问题。 (实际上,我认为是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)