将两个numpy数组中的值与'比较'

时间:2014-09-10 07:59:37

标签: python arrays numpy

我对numpy数组很新,在将一个数组与另一个数组进行比较时遇到了问题。

我有两个数组,例如:

a = np.array([1,2,3,4,5])
b = np.array([2,4,3,5,2])

我想做以下事情:

if b > a:
    c = b
else:
    c = a

所以我最终得到一个数组c = np.array([2,4,3,5,5])。

这可以被认为是取两个数组中每个元素的最大值。

但是,我遇到了错误

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

我尝试过使用这些但我不确定它是否适合我想要的东西。

是否有人能够提出解决此问题的建议?

5 个答案:

答案 0 :(得分:13)

您正在寻找功能np.fmax。它取两个数组的元素最大值,忽略NaN。

import numpy as np
a = np.array([1, 2, 3, 4, 5])
b = np.array([2, 4, 3, 5, 2])
c = np.fmax(a, b)

输出

array([2, 4, 3, 5, 5])

答案 1 :(得分:5)

与几乎所有其他numpy一样,比较是按元素完成的,返回一个完整的数组:

>>> b > a
array([ True,  True, False,  True, False], dtype=bool)

那么,这是真是假? if声明应该用它做什么?

Numpy的答案是它不应该试图猜测,它应该只是引发异常。

如果您想将其视为真,因为至少有一个值为true,请使用any

>>> if np.any(b > a): print('Yes!')
Yes!

如果您想将其视为假,因为并非所有值都为真,请使用all

>>> if np.all(b > a): print('Yes!')

但我很确定你不想要其中任何一个。您希望在数组上广播整个if / else

您当然可以将if / else逻辑包装为函数中的单个值,然后显式地vectorize并调用它:

>>> def mymax(a, b):
...     if b > a:
...         return b
...     else:
...         return a
>>> vmymax = np.vectorize(mymax)
>>> vmymax(a, b)
array([2, 4, 3, 5, 5])

这值得知道怎么做......但很少值得去做。使用本机矢量化函数通常采用更间接的方式 - 通常采用更多直接方式。


间接做到这一点的一种方法是使用True和False为数字1和0的事实:

>>> (b>a)*b + (b<=a)*a
array([2, 4, 3, 5, 5])

这将在1*b[i] + 0*a[i]时添加b>a,在0*b[i] + 1*a[i]时添加b<=a。有点难看,但不太难理解。有更清晰但更冗长的方式来写这个。

但是,让我们寻找更好的直接解决方案。


首先,请注意您的mymax函数与Python的内置max完全相同,包含2个值:

>>> vmymax = np.vectorize(max)
>>> vmymax(a, b)
array([2, 4, 3, 5, 5])

然后考虑一下这个有用的东西,numpy可能已经有了它。快速搜索会出现maximum

>>> np.maximum(a, b)
array([2, 4, 3, 5, 5])

答案 2 :(得分:1)

这是实现此目的的另一种方式

c = np.array([y if y>z else z for y,z in zip(a,b)])

答案 3 :(得分:1)

以下方法也有效:

  1. 使用numpy.maximum

    >>> np.maximum(a, b)

  2. 使用numpy.maxnumpy.vstack

    >>> np.max(np.vstack(a, b), axis = 0)

答案 4 :(得分:0)

可能不是最有效的方法,但这是对原始问题的更合适的答案:

import numpy as np

c = np.zeros(shape=(5,1))

a = np.array([1,2,3,4,5])
b = np.array([2,4,3,5,2])

for i in range(5):
    if b.item(i) > a.item(i):
        c[i] = b.item(i)
    else:
        c[i] = a.item(i)