在数组布尔数组中使用numpy的any()
我有一个由布尔值(真或假)组成的列表,举个例子,假设这个列表是 l = [[False, False], [True, False]]
。我需要把这个列表转换成一个包含布尔值的 numpy 数组。我把每个子列表都转换成了布尔数组,然后整个列表也转换成了 numpy 数组。现在我的实际列表有 121 个子列表,但使用 np.any()
函数时,只得到了五个结果,而不是预期的 121 个。我的代码是这样的:
>>> result = np.array([ np.array(extracted[aindices[i]:aindices[i + 1]]) for i in range(len(aux_regions)) ])
>>> np.any(result)
[false, false, false, false, false]
extracted[aindices[i]:aindices[i + 1]]
是我用来转换成布尔数组的子列表。整行生成的列表也被转换成了数组。
在第一个例子中,l
的预期结果是,对于每个子数组(假设列表已经转换),应该是 [False, True]
。
使用 np.any
时有什么问题吗?或者转换后的列表的数据类型是不是不对?
1 个回答
如果你有一个布尔值的列表列表,你可以不使用numpy,直接用简单的列表推导来处理:
In [1]: l = [[False, False], [True, False]]
In [2]: [any(subl) for subl in l]
Out[2]: [False, True]
如果每个子列表的长度都一样,你可以直接把这个列表传给 np.array
,这样就能得到一个布尔值的numpy数组:
In [3]: import numpy as np
In [4]: result = np.array(l)
In [5]: result
Out[5]:
array([[False, False],
[ True, False]], dtype=bool)
然后你可以在轴1上使用 any
方法,来获取每一行的结果:
In [6]: result.any(axis=1) # or `np.any(result, axis=1)`
Out[6]: array([False, True], dtype=bool)
如果子列表的长度不一样,那么用numpy数组可能就不太合适了。
这一部分的内容可以看作是对上面内容的补充。如果子列表的长度不固定,我推荐使用上面提到的列表推导。下面是一个使用numpy高级功能的替代方案。我之所以建议这个,是因为看起来你已经有了使用numpy的 reduceat
函数所需的数据结构。这个方法可以在不需要明确构建列表列表的情况下工作。
从你的代码中,我推测出以下几点:
extracted
是一个布尔值的列表。你正在把它拆分成子列表。aindices
是一个整数列表。aindices
中每一对连续的整数指定了在extracted
中的一个范围,这个范围就是一个子列表。len(aux_regions)
是子列表的数量;我称之为n
。aindices
的长度是n+1
,而aindices
中的最后一个值是extracted
的长度。
举个例子,如果数据看起来像这样:
In [74]: extracted
Out[74]: [False, True, False, False, False, False, True, True, True, True, False, False]
In [75]: aindices
Out[75]: [0, 3, 7, 10, 12]
这意味着有四个子列表:
In [76]: extracted[0:3]
Out[76]: [False, True, False]
In [77]: extracted[3:7]
Out[77]: [False, False, False, True]
In [78]: extracted[7:10]
Out[78]: [True, True, True]
In [79]: extracted[10:12]
Out[79]: [False, False]
有了这些数据结构,你就可以使用numpy的 reduceat
功能。在这个情况下,ufunc
是 logical_or
。你可以用这一行代码来计算结果:
In [80]: np.logical_or.reduceat(extracted, aindices[:-1])
Out[80]: array([ True, True, True, False], dtype=bool)