【问题标题】:Using numpy any() in bool array of arrays在数组的布尔数组中使用 numpy any()
【发布时间】:2014-10-20 12:34:37
【问题描述】:

我有一个由布尔组成的列表列表,比如说l = [[False, False], [True, False]],我需要将l 转换为布尔数组的numpy 数组。我将每个子列表转换为布尔数组,并将整个列表也转换为 numpy 数组。我当前的真实列表有 121 个子列表,np.any() 的结果仅抛出 5 个结果,而不是预期的 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 有什么问题?还是转换后的列表的数据类型不正确?

【问题讨论】:

  • 为什么你想要一个数组而不是二维数组或数组列表?数组数组往往会导致混乱——你在它上面广播的任何东西通常都会将每个子数组视为一个 Python 对象,而不是 numpily 做任何事情。
  • @abarnet 确切地说,我应该使用哪种转换来让 numpy.any() 按预期工作?

标签: python arrays numpy boolean


【解决方案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) 是子列表的数量;我会打电话给naindices的长度为n+1aindices的最后一个值为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 特性了。在这种情况下,ufunclogical_or。你可以用这一行来计算结果:

In [80]: np.logical_or.reduceat(extracted, aindices[:-1])
Out[80]: array([ True,  True,  True, False], dtype=bool)

【讨论】:

  • 如果布尔列表的长度不同,是否会失败?因为我的列表有很多长度。
  • 在这种情况下,numpy 数组可能不适合使用。
  • 基本上我将不得不比较执行时间。到目前为止,您的第一种方法在代码和数据结构管理方面都很简单,这让我很高兴哈哈。我正在开发的代码以及您的出色回答导致时间执行从一分钟缩短到 16 秒(处理数千个数据)
猜你喜欢
  • 2020-06-07
  • 2021-01-06
  • 2017-09-24
  • 2016-12-08
  • 2016-03-11
  • 2018-05-20
  • 2012-04-10
  • 2023-01-20
  • 1970-01-01
相关资源
最近更新 更多