此问题与以下帖子有关:Replacing Numpy elements if condition is met。
假设我有两个一维的numpy数组a
和b
,每行有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循环?
答案 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]])