关于numpy库的where函数的用法

这里是numpy库学习笔记之where函数,收到请回答。
不知道numpy库where函数的用法前
当我们需要对数组时进行条件逻辑表述时,因为前面说到过,numpy库的很多操作都可以用python原生的处理方式。所以我们第一个想到的就是 的三元表达式结构。
所以我们先举一个例子看看这个方法是否可行。
首先我们先创建两个一维数值数组和一个一维布尔类型的数组,分别赋值到xarr,yarr与cond:

In [165]: xarr = np.array([1.1, 1.2, 1.3, 1.4, 1.5])

In [166]: yarr = np.array([2.1, 2.2, 2.3, 2.4, 2.5])

In [167]: cond = np.array([True, False, True, True, False])

假设我们想要根据cond布尔数组里的布尔值来分别选取xarr和yarr的值:当同一位置cond中的值为True时,选取xarr的值,否则从yarr中选取然后形成一个新的一维数值数组。

In [168]: result = [(x if c else y)
   .....:           for x, y, c in zip(xarr, yarr, cond)]

In [169]: result
Out[169]: [1.1000000000000001, 2.2000000000000002, 1.3, 1.3999999999999999, 2.5]

首先,乍一看这个是什么东西啊?怎么这么一长串数字啊?实际上这里运用到了浮点数的运算,因为有些小数用二进制的表示是无穷的,所以有时候丢失精确度是无法避免的。
比如用python进行如下计算,得出的结果就很典型。

In [1]: 0.1 + 0.2
Out[1]: 0.30000000000000004

0.1 + 0.2先转换成二进制进行计算,获得的二进制值再返回显示到浮点数,而该二进制值对应的浮点数就是一个无限小数,就显示成了这样。

好了,我们回到where函数上来。这种三元表达式比较直观易懂,但是它有两个问题。第一,它对大数组的处理速度不是很快(因为所有工作都是由纯python完成的),而numpy库使用了python的api接口,可以直接调用低级语言对内存进行直接操作,加快大数据处理时的效率。第二,无法用于多维数组。若使用np.where,则该功能写得非常简洁(不简洁也就没必要做成一个函数了)。

In [170]: result = np.where(cond, xarr, yarr)

In [171]: result
Out[171]: array([ 1.1,  2.2,  1.3,  1.4,  2.5])


np.where的第二和第三个参数不必是数组,也可以是标量值1,2,3……在数据分析过程中,where函数通常用于根据原数组而产生一个新的数组。假设有一个随机数据组成的二维数组,你想要把数组中所有的正值替换为2,将所有的负值替换为-2。若利用np.where,则会非常简单:

In [172]: arr = np.random.randn(4, 4)

In [173]: arr
Out[173]: 
array([[-0.5031, -0.6223, -0.9212, -0.7262],
       [ 0.2229,  0.0513, -1.1577,  0.8167],
       [ 0.4336,  1.0107,  1.8249, -0.9975],
       [ 0.8506, -0.1316,  0.9124,  0.1882]])

In [174]: arr > 0
Out[174]: 
array([[False, False, False, False],
       [ True,  True, False,  True],
       [ True,  True,  True, False],
       [ True, False,  True,  True]], dtype=bool)

In [175]: np.where(arr > 0, 2, -2)
Out[175]: 
array([[-2, -2, -2, -2],
       [ 2,  2, -2,  2],
       [ 2,  2,  2, -2],
       [ 2, -2,  2,  2]])

使用np.where,可以将标量和数组结合起来。例如,我们可用常数2替换arr中所有正的值:

In [176]: np.where(arr > 0, 2, arr) # set only positive values to 2
Out[176]: 
array([[-0.5031, -0.6223, -0.9212, -0.7262],
       [ 2.    ,  2.    , -1.1577,  2.    ],
       [ 2.    ,  2.    ,  2.    , -0.9975],
       [ 2.    , -0.1316,  2.    ,  2.    ]])

而实际上,除了处理数组类型为数值的数组以外,还可以处理其他类型的数组,如数组类型为字符串的数组和布尔类型的数组等等。
把where的参数(x,y,z)看成:
三元表达式的(if语句,x,else语句)。

文章代码引用自:《利用Python进行数据分析·第2版》第4章 NumPy基础:数组和矢量计算
作者:SeanCheney
感谢SeanCheney同意引用。

你可能感兴趣的:(关于numpy库的where函数的用法)