numpy如何按条件给元素赋值np.where、np.clip
作者:大Py
numpy按条件给元素赋值np.where、np.clip
np.where(condition, [x, y])
属于numpy的元素选择函数
Parameters:
- condition:条件,是一个类array的bool数组。个人根绝是一个bool mask。
- x,y:类array数组。当condition是True时返回x,为False时返回y。x与必须同时给出或者同时不给出,不能只给出一个。当都不给出时,依据nonzero返回处理。
Returns:
1、当只给出condition时,返回一个tuple,该tuple就是满足condition的元素的index。tuple元素的个数是原来array的维度,一维一个元素,二维两个元素。每个元素对应位置数据组合起来就是满足condition的元素的index。
2、给出x和y,返回一个和condition相同形状的数组。这里x与y的shape很重要,而且由condition的shape决定。当condition是(k,m,n)时,x与y 的shape依赖condition的维度。
x,y的shape如下如图:
当满足条件时,会根据x和y的维度取替换condition上的对应值。
使用举例1:
arr = np.arange(12).reshape(3,4) arr array([[ 0, 1, 2, 3], [ 4, 5, 6, 7], [ 8, 9, 10, 11]]) np.where(arr > 6) (array([1, 2, 2, 2, 2], dtype=int64), array([3, 0, 1, 2, 3], dtype=int64))
返回一个tuple,两个元素,因为arr的shape是(3,4)是二维的。第一个元素是行,第二个元素是列。第一个满足条件的元素的第1行第3列的元素,即元素7。
使用举例2:
np.where(arr > 6, 0, arr) array([[0, 1, 2, 3], [4, 5, 6, 0], [0, 0, 0, 0]])
满足条件的替换为0,不满足的返回arr中的值。从arr取值时是按照索引取选取的。这里要注意,当x或y的维度小于condition的维度时,忽略高维度的索引,比如忽略k,只根据m和n的值从x或y取数。
个人理解就一句话:用同一个维度(粒度)上的数据取替换同一个维度(粒度)上的数据。
实际操作中使用较多的还是用(k,m,n)原数组或者常数替换操作,即替换原来数组中的某些值。
np.clip(a, a_min, a_max, out=None)
Params:
a_min, a_max:整数、类array数组或者None,下面逐一解读。
- 整数时,将小于a_min的值替换为a_min。然后,将大于a_max的值替换为a_max。处于两者之间数保持不变。
- 类array时,当a的形状是(m,n),a_min、a_max是(m,1)、(m,)或者是(m,n)。通俗讲,要么给a中每一个一维数组中每一个元素提供一个比较值,要么给a中每个一维数组提供一个统计的比较值,要么提供一个与一维数组形状形同的数组,然后广播。扩展到3维也是一样的道理。
- None,当a_min为None时,表示小于amax的值保留原值。当a_max为None时,表示大于amin的值保留原值。 a_min和a_max只能有一个是None。
Returns:
返回一个与传入数组形状相同的数组。
举例:
arr array([[ 7, -3, 12], [14, 0, 8]])
给二维数组中每一个数组传入一个统一的比较值
b array([[1], [2]]) np.clip(arr,b,None) array([[ 7, 1, 12], [14, 2, 8]])
传入一个和一维数组相同形状的数组,然后沿着轴0广播。
b array([1, 4, 9]) np.clip(arr,b,arr) array([[ 7, 4, 12], [14, 4, 9]])
Numpy.where()/np.where() 函数的使用
修改数组中符合条件的元素值/查找数组中符合要求的元素的位置
numpy.where() 用法
1. np.where(condition, x, y):用于修改满足条件的元素值
用法解释:满足condition将数组元素修改为x,否则修改为y,最后生成一个新的数组。
注意:np.where不会修改原数组的数值,而会生成一个新的数组
- 1.1 一维数组
# 生成-5到4的一维数组 arr1 = np.arange(-5,5) print('原数组 :',arr1) arr2 = np.where(arr1>0,1,-1) print('查看原数组是否修改:',arr1) print('修改后的数组 :',arr2)
输出结果:
原数组 : [-5 -4 -3 -2 -1 0 1 2 3 4]
查看原数组是否修改: [-5 -4 -3 -2 -1 0 1 2 3 4]
修改后的数组 : [-1 -1 -1 -1 -1 -1 1 1 1 1]
如果只对一个条件进行修改:>0 保持不变,小于0变为-1
将where语句修改为如下即可:
arr2 = np.where(arr1>0,arr1,-1)
即,不修改的位置为arr原数组的值
- 1.2 二维数组
arr1 = np.arange(-5,5).reshape(2,5) print('原数组',arr1,sep='\n') arr2 = np.where(arr1>0,1,-1) print('修改后的数组',arr2,sep='\n')
输出结果:
原数组
[[-5 -4 -3 -2 -1]
[ 0 1 2 3 4]]
修改后的数组
[[-1 -1 -1 -1 -1]
[-1 1 1 1 1]]
2 np.where(condition): 用于找出满足条件的元素位置(坐标)
- 2.1 一维数组
# 生成-5到4的一维数组 arr1 = np.arange(-5,5) print(arr1) arr2 = np.where(arr1>0) print(arr2)
[-5 -4 -3 -2 -1 0 1 2 3 4] (array([6, 7, 8, 9], dtype=int64),)
上述结果说明:arr1 > 0的元素所在的位置是[6,7,8,9]
并且arr2是个元组的类型,其中包含着数组类型的位置坐标。
print(type(arr2)) print(type(arr2[0])) ------------------------- 结果: <class 'tuple'> <class 'numpy.ndarray'>
2.1.1利用生成的元素进行索引数据:
- 法1直接利用元组索引,比较方便
- 法2利用数组进行索引
# 索引法1 print(arr1[arr2]) # 索引法2 print(arr1[arr2[0]])
2.1.2 不满足条件的情况
# 不满足条件 arr1 = np.arange(-5,5) arr3 = np.where(arr1 < -5) print(arr3) print(arr1[arr3]) -------------------------------- 结果: (array([], dtype=int64),) []
2.2.1判断满足的条件的元素个数
利用数组的.size属性很好判断
arr1 = np.arange(-5,5) arr2 = np.where(arr1 > 0) arr3 = np.where(arr1 < -5) print(arr2[0].size) print(arr3[0].size) ------------------------------------ 结果: 4 0
- 2.2二维数组
二维数组与一维数组类似,但是返回的元组中有两个数组:分别表示行的索引和列的索引
arr1 = np.arange(0,10).reshape(2,5) print(arr1) arr2 = np.where(arr1>3) print(arr2)
结果:
[[0 1 2 3 4]
[5 6 7 8 9]]
(array([0, 1, 1, 1, 1, 1], dtype=int64), array([4, 0, 1, 2, 3, 4], dtype=int64))
从结果中我们可以看到,元组中的第一个数组表示的是行的索引,第二个数组是列的索引
所以满足>3的元素位置是:[0,4],[1,0],…
索引方法类似
# 索引 arr1[arr2] ----------- array([4, 5, 6, 7, 8, 9])
总结
以上为个人经验,希望能给大家一个参考,也希望大家多多支持脚本之家。