【问题标题】:ValueError with union of two arrays using the OR operator使用 OR 运算符合并两个数组的 ValueError
【发布时间】:2018-12-18 23:14:00
【问题描述】:

我正在使用 Python 和 numpy,其中有几个相同形状的 numpy 数组,我正在尝试创建这些数组的联合。这些数组只包含 0 和 1,基本上我想使用 OR 操作将它们合并到一个新数组中。所以,我做了以下事情:

import numpy as np

segs = list()
a = np.ones((10, 10)).astype('uint8')
b = np.zeros((10, 10)).astype('uint8')
segs.append(a)
segs.append(b)

mask = np.asarray([any(tup) for tup in zip(*segs)]).astype('uint8')

最后一句我得到了错误:

ValueError: The truth value of an array with more than one element is ambiguous. Use a.any() or a.all()

如果我使用np.any,不知何故我的数组形状现在只是(10,)。如何在不显式循环数组的情况下创建此合并?

编辑

mask = np.asarray([any(tup) for tup in zip(segs)]).astype('uint8')

也会导致同样的错误。

【问题讨论】:

  • a | b 怎么样?
  • 是的,但理论上我可以有很多数组。我这样做是为了创建一个简单的可重现程序。大小也可能只在运行时才知道
  • 那么np.logical_or.reduce((a, b))呢?您当前的代码在每次迭代中对两个 NumPy 数组的元组调用 any,这显然是行不通的。
  • 啊啊啊……这行得通!你想把它写成答案吗?
  • Python 逻辑运算符不适用于 numpy 数组(iforany 等)。像|np.any 这样的 Numpy 更好。

标签: python arrays numpy


【解决方案1】:

您的 segs 是 2 个数组的列表:

In [25]: segs = [np.ones((3,6),'uint8'), np.zeros((3,6),'uint8')]
In [26]: [tup for tup in zip(*segs)]
Out[26]: 
[(array([1, 1, 1, 1, 1, 1], dtype=uint8),
  array([0, 0, 0, 0, 0, 0], dtype=uint8)),
 (array([1, 1, 1, 1, 1, 1], dtype=uint8),
  array([0, 0, 0, 0, 0, 0], dtype=uint8)),
 (array([1, 1, 1, 1, 1, 1], dtype=uint8),
  array([0, 0, 0, 0, 0, 0], dtype=uint8))]

zip 生成一维数组的元组(将两个数组的行配对)。应用于数组的 Python any 会产生歧义错误 - 这对于其他逻辑 Python 操作(如 ifor 等)确实如此,它们需要标量 True/False

您尝试了np.any - 将数组元组转换为二维数组。但如果没有axis 参数,它适用于扁平版本,返回一个标量True/False。但是使用轴参数,我们可以跨行应用这个any

In [27]: [np.any(tup, axis=0) for tup in zip(*segs)]
Out[27]: 
[array([ True,  True,  True,  True,  True,  True]),
 array([ True,  True,  True,  True,  True,  True]),
 array([ True,  True,  True,  True,  True,  True])]

按照评论中的建议使用logical_or ufunc:

In [31]: np.logical_or(segs[0],segs[1])
Out[31]: 
array([[ True,  True,  True,  True,  True,  True],
       [ True,  True,  True,  True,  True,  True],
       [ True,  True,  True,  True,  True,  True]])
In [32]: np.logical_or.reduce(segs)
Out[32]: 
array([[ True,  True,  True,  True,  True,  True],
       [ True,  True,  True,  True,  True,  True],
       [ True,  True,  True,  True,  True,  True]])

使用“|”运算符不太一样:

In [33]: segs[0] | segs[1]
Out[33]: 
array([[1, 1, 1, 1, 1, 1],
       [1, 1, 1, 1, 1, 1],
       [1, 1, 1, 1, 1, 1]], dtype=uint8)

它使用segs[0].__or__(segs[1]) 方法。我必须检查文档以了解发生了什么。对uint8(或其他数值)的应用不同于对bool 的应用。几乎看起来像max

【讨论】:

    猜你喜欢
    • 2015-05-10
    • 1970-01-01
    • 2020-01-20
    • 2015-07-07
    • 1970-01-01
    • 1970-01-01
    • 2013-05-09
    • 2015-07-08
    • 1970-01-01
    相关资源
    最近更新 更多