如何使用Python numpy.where()方法

时间:2020-02-23 14:43:05  来源:igfitidea点击:

在Python中,我们可以使用numpy.where()函数根据条件从numpy数组中选择元素。

不仅如此,如果条件满足,我们可以对这些元素执行一些操作。

让我们来看一些示例,看看如何使用此功能!

Python numpy.where()的语法

此函数接受类似numpy的数组(例如,整数/布尔值的NumPy数组)。

在根据条件过滤后,它返回一个新的numpy数组,它是一个类似于numpy的布尔值数组。

例如," condition"可以采用array([True,True,True")的值,它是一个类似numpy的布尔数组。
(默认情况下,NumPy仅支持数字值,但我们也可以将其强制转换为bool)。

例如,如果将条件应用于数组时,如果条件是数组(True,True,False)),而我们的数组是a = ndarray(1,2,3) (a [:, condition]),我们将得到数组ndarray(1 2)。

import numpy as np

a = np.arange(10)
print(a[a <= 2]) # Will only capture elements <= 2 and ignore others

输出

array([0 1 2])

注意:相同的条件条件也可以表示为<=2。
这是条件数组的推荐格式,因为将其写为布尔数组非常繁琐

但是,如果我们想保留结果的维数而不丢失我们原始数组中的元素,该怎么办?我们可以为此使用numpy.where()。

numpy.where(condition [, x, y])

我们还有两个参数" x"和" y"。
那些是什么?

基本上,这就是说,如果条件对我们数组中的某个元素成立,那么新数组将从x中选择元素。

否则,如果为假,将采用y中的元素。

这样,我们最终的输出数组将是一个数组,其中条件为True的元素来自x,条件为False的元素来自y。

请注意,尽管x和y是可选的,但如果您指定x,则还必须指定y。
这是因为在这种情况下,输出数组的形状必须与输入数组的形状相同。

注意:相同的逻辑也适用于一维和多维数组。
在这两种情况下,我们都根据条件进行过滤。
还要记住," x"," y"和" condition"的形状是一起广播的。

现在,让我们看一些示例,以正确理解此功能。

使用Python numpy.where()

假设我们只想从numpy数组中获取正数元素,并将所有负数元素设置为0,让我们使用numpy.where()编写代码。

1.用numpy.where()替换Elements

我们将在此处使用二维随机数组,仅输出正数元素。

import numpy as np

# Random initialization of a (2D array)
a = np.random.randn(2, 3)
print(a)

# b will be all elements of a whenever the condition holds true (i.e only positive elements)
# Otherwise, set it as 0
b = np.where(a > 0, a, 0)

print(b)

可能的输出

[[-1.06455975  0.94589166 -1.94987123]
 [-1.72083344 -0.69813711  1.05448464]]
[[0.         0.94589166 0.        ]
 [0.         0.         1.05448464]]

如您所见,现在仅保留了积极元素!

2.仅在有条件的情况下使用numpy.where()

上面的代码可能有些混乱,因为你们中的一些人可能认为更直观的方法是简单地编写如下条件:

import random
import numpy as np

a = np.random.randn(2, 3)
b = np.where(a > 0)
print(b)

如果您现在尝试运行上述代码,并进行此更改,则会得到如下输出:

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

如果仔细观察," b"现在是一个numpy数组的元组。
每个数组都是一个正元素的位置。
这是什么意思?

只要我们提供一个条件,该函数实际上就相当于np.asarray.nonzero()

在我们的示例中,np.asarray(a> 0)将在应用条件后返回类似布尔值的数组,而np.nonzero(arr_like)将返回arr_like的非零元素的索引。

因此,我们现在来看一个更简单的示例,该示例向我们展示了使用numpy的灵活性。

import numpy as np

a = np.arange(10)

b = np.where(a < 5, a, a * 10)

print(a)
print(b)

乌普图

[0 1 2 3 4 5 6 7 8 9]
[ 0  1  2  3  4 50 60 70 80 90]

这里的条件是" a <5",它将是类似numpy的数组" [True True True True True True False False False False False]"," x"是数组a,而" y"是数组a 10。
因此,只有<5时,我们才能从a中选择;如果> 5则我们就从
10中选择。

因此,这通过乘以10来转换> = 5的所有元素。
这确实是我们得到的!

用numpy.where()广播

如果我们提供所有的condition,x和y数组,numpy将一起广播它们。

import numpy as np

a = np.arange(12).reshape(3, 4)

b = np.arange(4).reshape(1, 4)

print(a)
print(b)

# Broadcasts (a < 5, a, and b * 10)
# of shape (3, 4), (3, 4) and (1, 4)
c = np.where(a < 5, a, b * 10)

print(c)

输出

[[ 0  1  2  3]
 [ 4  5  6  7]
 [ 8  9 10 11]]
[[0 1 2 3]]
[[ 0  1  2  3]
 [ 4 10 20 30]
 [ 0 10 20 30]]

同样,这里是根据条件选择输出的,所以所有元素(但这里b)都以a的形式广播。
(其维度之一只有一个元素,因此在广播过程中不会出现错误)

因此,b将变为[[[0 1 2 3] [0 1 2 3] [0 1 2 3]],现在,我们甚至可以从此广播数组中选择元素。

因此,输出的形状与" a"的形状相同。