当存在多个条件时,替换numpy数组中的元素

时间:2018-03-06 16:22:56

标签: python arrays python-3.x numpy

此问题与以下帖子有关:Replacing Numpy elements if condition is met

假设我有两个一维的numpy数组ab,每行有50行。

我想创建一个包含50行的数组c,每个行将取值0-4,具体取决于是否满足条件:

if a > 0 the value in the corresponding row of c should be 0
if a < 0 the value in the corresponding row of c should be 1
if a > 0 and b < 0 the value in the corresponding row of c should be 2
if b > 0 the value in the corresponding row of c should be 3

我想这里更广泛的问题是我如何为一个特定的值分配 有多个条件时的数组。我尝试过上面提到的帖子的变化,但我没有成功。

关于我如何实现这一点的任何想法,最好不要使用 for循环?

3 个答案:

答案 0 :(得分:3)

直接的解决方案是按顺序应用分配。

In [18]: a = np.random.choice([-1,1],size=(10,))
In [19]: b = np.random.choice([-1,1],size=(10,))
In [20]: a
Out[20]: array([-1,  1, -1, -1,  1, -1, -1,  1,  1, -1])
In [21]: b
Out[21]: array([-1,  1,  1,  1, -1,  1, -1,  1,  1,  1])

从一个带有'default'值的数组开始:

In [22]: c = np.zeros_like(a)

应用第二个条件:

In [23]: c[a<0] = 1

第三个需要一点小心,因为它结合了两个测试。 ()这里的事情:

In [25]: c[(a>0)&(b<0)] = 2

最后一次:

In [26]: c[b>0] = 3
In [27]: c
Out[27]: array([1, 3, 3, 3, 2, 3, 1, 3, 3, 3])

看起来所有的初始0都被覆盖了。

对于阵列中的许多元素,以及一些测试,我不会担心速度。注重清晰度和表现力,而不是紧凑性。

where有一个3参数版本,可以在值或数组之间进行选择。但我很少使用它,也没有看到很多关于它的问题。

In [28]: c = np.where(a>0, 0, 1)
In [29]: c
Out[29]: array([1, 0, 1, 1, 0, 1, 1, 0, 0, 1])
In [30]: c = np.where((a>0)&(b<0), 2, c)
In [31]: c
Out[31]: array([1, 0, 1, 1, 2, 1, 1, 0, 0, 1])
In [32]: c = np.where(b>0, 3, c)
In [33]: c
Out[33]: array([1, 3, 3, 3, 2, 3, 1, 3, 3, 3])

这些where可以链接在一行上。

c = np.where(b>0, 3, np.where((a>0)&(b<0), 2, np.where(a>0, 0, 1)))

答案 1 :(得分:1)

正如@chrisz指出的那样,你目前有重叠的条件。这就是我如何使用多个if语句:

import numpy as np
a = np.random.random(50)*10 - 10
b = np.random.random(50)*10 - 10
c = [0*(a>0)*(b<0) + 1*(a<0) + 3*(a==0)*(b>0)]

如果为true,则compare语句返回1,否则返回0。通过将它们相乘并添加不同的语句,您可以创建多个if语句。但是,如果if语句不重叠,这只能起作用。

答案 2 :(得分:1)

可以通过np.select来解决此问题。您只需要提供条件和选择的列表:

np.random.seed(0)

a = np.random.randint(-10, 10, (5, 5))
b = np.random.randint(-10, 10, (5, 5))

conditions = [b > 0, (a > 0) & (b < 0), a < 0, a > 0]
choices = [3, 2, 1, 0]

res = np.select(conditions, choices)

array([[3, 3, 1, 3, 1],
       [3, 3, 3, 3, 3],
       [1, 2, 1, 1, 1],
       [0, 2, 3, 3, 1],
       [1, 2, 2, 2, 1]])