我们相信:世界是美好的,你是我也是。平行空间的世界里面,不同版本的生活也在继续...

苏南大叔在本文中,要来说说numpy的一个数据筛选函数.where(),这个函数是典型的一个函数三种用法。不知道为啥要统一到一个.where()函数里面。在网上,说这个.where()函数是获取"不为0数据"的坐标的。这个说法很片面,这只是其中一种用法罢了。本文的观点可能和网上大多数的观点存在出入,欢迎留言给我。

苏南大叔:基于python,如何理解numpy数据筛选where函数三种用法? - numpy-where-三种用法
基于python,如何理解numpy数据筛选where函数三种用法?(图2-1)

苏南大叔的“程序如此灵动”技术博客,记录苏南大叔的代码经验总结。本文测试环境:win10python@3.11.0numpy@1.24.2。这个.where(),定义在numpy上了,并没有定义在ndarray类型上。所以,只能写成np.where(),不能写成_ndarray.where()。这是个单一的被动函数写法。

第一种用法,返回不为空值的元素的坐标

np.where(target)

在这第一种用法里面,np.where(_ndarray)要求_ndarray的元素不为零【网上流传的说法】。苏南大叔认为:要求是不为空。

import numpy as np

s = np.array([[True, False], [None, np.nan], [0, 1], ["9", ""]])
sn = np.where(s)
print(s, type(s))
print(sn, type(sn))
print(s[sn])     # [True nan 1 '9']

输出:

[[True False]
 [None nan]
 [0 1]
 ['9' '']] 
<class 'numpy.ndarray'>

(array([0, 1, 2, 3], dtype=int64), 
 array([0, 1, 1, 0], dtype=int64)) 
<class 'tuple'>

[True nan 1 '9']

这是第一个返回值为tuple的例子,其格式是([x1,x2...],[y1,y2...])。所以,非空值的数据是:
1、(0,0)=>True
2、(1,1)=>np.nan
3、(2,1)=>1
4、(3,0)=>'9'

在这个例子里面,可以看到:

  • np.nan/1/True/普通字符串,没有被当作空值。
  • 0/False/None/空字符串,被处理成了空值。

苏南大叔:基于python,如何理解numpy数据筛选where函数三种用法? - where代码结果截图
基于python,如何理解numpy数据筛选where函数三种用法?(图2-2)

上述结论得出后,可以翻过来再看原来的any()all()的文章:

第二种用法,返回符合条件表达的数据

np.where(condition)

这是第二种使用方法,注意说法的变化,这里对数据并没有非零或者非空的要求。

import numpy as np
s = np.array([[1, 2, 3], [4, 5, 6], [7, 8, 9]])
sn = np.where(s >= 3)  # 找出所有>=3的元素的位置
print(s,type(s))
print(sn,type(sn))
print(s[sn])  # [3 4 5 6 7 8 9]

输出:

[[1 2 3]
 [4 5 6]
 [7 8 9]] 
<class 'numpy.ndarray'>

(array([0, 1, 1, 1, 2, 2, 2], dtype=int64), 
 array([2, 0, 1, 2, 0, 1, 2], dtype=int64)) 
<class 'tuple'>

[3 4 5 6 7 8 9]

第三种用法,根据条件修改后返回数据

np.where(condition,x,y)

满足条件condition则返回x, 不满足则输出y

import numpy as np

s = np.array([[1, 2, 3], [4, 5, 6], [7, 8, 9]])
sn = np.where(s >= 3, s * 2, 0)  # 找出所有>=3的元素的位置
print(s, type(s))
print(sn, type(sn))
# IndexError: index 6 is out of bounds for axis 0 with size 3
# print(s[sn])

输出:

[[1 2 3]
 [4 5 6]
 [7 8 9]] 
<class 'numpy.ndarray'>

[[ 0  0  6]
 [ 8 10 12]
 [14 16 18]] 
<class 'numpy.ndarray'>

这种用法,仅是返回合适的ndarray数据,而不是返回对应数据的tuple类型坐标。所以试图使用s[sn]的时候,并不会得到期待的数据,甚至是会报错。

表格总结

np.where()参数返回值返回值类型
第一种用法_ndarray不为空值的元素的坐标tuple
第二种用法condition符合条件的元素的坐标tuple
第三种用法condition,x,y根据条件分别对符合的数据和不符合的数据进行处理ndarray

参考文献

结束语

更多更好的苏南大叔的python经验文章,链接如下:

如果本文对您有帮助,或者节约了您的时间,欢迎打赏瓶饮料,建立下友谊关系。
本博客不欢迎:各种镜像采集行为。请尊重原创文章内容,转载请保留作者链接。

 【福利】 腾讯云最新爆款活动!1核2G云服务器首年50元!

 【源码】本文代码片段及相关软件,请点此获取更多信息

 【绝密】秘籍文章入口,仅传授于有缘之人   python