numpy的排序和集合操作
numpy的排序
import numpy as np
排序 np.sort()
基本使用
np.sort(x,[axis = -1 ,order = None])
对数组x进行从小到大排序,order可以指定按照哪一个属性排序
np.sort(x) 表示对x进行从小到大的排序
x = np.array([1,5,2,8,1])
y = np.sort(x)
print(y)
# [1 1 2 5 8]
若x是一个二维数组,表示对每一行元素进行从小到大排序
np.random.seed(666)
x = np.random.rand(5,5)*10
x = np.around(x,2)
print(x)
# [[7. 8.44 6.77 7.28 9.51]
# [0.13 4.14 0.49 1. 5.08]
# [2. 7.44 1.93 7.01 2.93]
# [7.74 0.05 1.13 1.11 2.48]
# [0.23 7.27 3.4 1.98 9.09]]
y = np.sort(x)
print(y)
# [[6.77 7. 7.28 8.44 9.51]
# [0.13 0.49 1. 4.14 5.08]
# [1.93 2. 2.93 7.01 7.44]
# [0.05 1.11 1.13 2.48 7.74]
# [0.23 1.98 3.4 7.27 9.09]]
当 x 是多维数组时,np.sort(x) = np.sort(x,axis= -1 ) 也就是对数组x的最后一个维度的元素进行排序
当x是二维数组时,np.sort(x) = np.sort(x,axis= -1 ) = np.sort(x, axis= 1) 表示按行排序
y = np.sort(x,axis=1)
print(y)
# [[6.77 7. 7.28 8.44 9.51]
# [0.13 0.49 1. 4.14 5.08]
# [1.93 2. 2.93 7.01 7.44]
# [0.05 1.11 1.13 2.48 7.74]
# [0.23 1.98 3.4 7.27 9.09]]
z = np.sort(x,axis= -1)
print(z)
# [[6.77 7. 7.28 8.44 9.51]
# [0.13 0.49 1. 4.14 5.08]
# [1.93 2. 2.93 7.01 7.44]
# [0.05 1.11 1.13 2.48 7.74]
# [0.23 1.98 3.4 7.27 9.09]]
二维数组中,np.sort(x,axis=0) 表示按列排序
y = np.sort(x,axis=0)
print(y)
# [[0.13 0.05 0.49 1. 2.48]
# [0.23 4.14 1.13 1.11 2.93]
# [2. 7.27 1.93 1.98 5.08]
# [7. 7.44 3.4 7.01 9.09]
# [7.74 8.44 6.77 7.28 9.51]]
order参数
order参数可以指定按照哪一个属性进行排序
dt = np.dtype([('name','S10'),('age',np.int)])
a = np.array([('Mike',21),('Nancy',25),('Bob',17),('Jane',27)],dtype=dt)
print(a)
# [(b'Mike', 21) (b'Nancy', 25) (b'Bob', 17) (b'Jane', 27)]
在这里,我们自定义了一个数据结构,属性名有 name 和 age
使用 order 参数指定按照 name 属性排序
b = np.sort(a,order='name')
print(b)
# [(b'Bob', 17) (b'Jane', 27) (b'Mike', 21) (b'Nancy', 25)]
使用 order 参数指定按照 age 属性排序
b = np.sort(a,order='age')
print(b)
# [(b'Bob', 17) (b'Mike', 21) (b'Nancy', 25) (b'Jane', 27)]
排序后的下标 np.argsort()
对数组 x 排序,返回排序后的元素下标,但不改变x
np.random.seed(666)
x = np.random.randint(0,10,10)
print(x)
# [2 6 9 4 3 1 0 8 7 5]
y = np.argsort(x)
print(y)
# [6 5 0 4 3 9 1 8 7 2]
print(x[y])
# [0 1 2 3 4 5 6 7 8 9]
我们还可以使用这个函数将原数组x进行从大到小排序
y = np.argsort(-x)
print(y)
# [2 7 8 1 9 3 4 0 5 6]
print(x[y])
# [9 8 7 6 5 4 3 2 1 0]
最大值下标 np.argmax()
返回最大值的下标
一维数组中的argmax
x = np.random.randint(1,10,6)
print(x)
# [1 7 7 1 4 3]
y = np.argmax(x)
print(y)
# 1
print(x[y])
# 7
二维数组中的argmax
np.random.seed(666)
x = np.random.randint(1,10,[3,4])
print(x)
# [[3 7 5 4]
# [2 1 9 8]
# [6 3 6 6]]
y = np.argmax(x,axis=0)
print(y)
# [2 0 1 1]
z = np.argmax(x,axis=1)
print(z)
# [1 2 0]
最小值下标 np.argmin()
返回最小值的下标
一维数组中的argmin
np.random.seed(666)
x = np.random.randint(1,10,10)
print(x)
# [3 7 5 4 2 1 9 8 6 3]
y = np.argmin(x)
print(y)
# 5
print(x[y])
# 1
二维数组中的argmin
np.random.seed(666)
x = np.random.randint(1,10,[3,4])
print(x)
# [[3 7 5 4]
# [2 1 9 8]
# [6 3 6 6]]
y = np.argmin(x,axis=0)
print(y)
# [1 1 0 0]
z = np.argmin(x,axis=1)
print(z)
# [0 1 1]
非0元素下标 np.nonzero()
返回非0元素的下标,返回的是一个元组
x = np.array([0,2,3])
y = np.nonzero(x)
print(y)
# (array([1, 2], dtype=int64),)
print(x[y])
# [2 3]
print(type(y))
# <class 'tuple'>
条件判断 np.where()
np.where( condition , [ x , y ] )
若给给出了 x,y , 满足条件的转换为x,否则转换为y
若未给出 x,y,则返回一个tuple,为满足条件的元素的下标,此时等价于 np.nonzero()
x = np.arange(10)
y = np.where(x<5,x,10*x)
print(y)
# [ 0 1 2 3 4 50 60 70 80 90]
x = np.array([
[0,1,2],
[0,2,4],
[0,3,6]
])
y = np.where(x<4,x,-1)
print(y)
# [[ 0 1 2]
# [ 0 2 -1]
# [ 0 3 -1]]
若未给出 x,y,则返回一个tuple,为满足条件的元素的下标,此时等价于 np.nonzero()
x = np.arange(1,8)
y = np.where(x>5)
print(y)
# (array([5, 6], dtype=int64),)
print(type(y))
# <class 'tuple'>
print(x[y])
# [6 7]
z = np.nonzero(x>5)
print(z)
# (array([5, 6], dtype=int64),)
print(type(z))
# <class 'tuple'>
print(x[z])
# [6 7]
计数
计算非0元素个数 np.count_nonzero()
np.count_nonzero(x) 不指定axis,表示求所有的非0元素个数
x = np.eye(4)
print(x)
# [[1. 0. 0. 0.]
# [0. 1. 0. 0.]
# [0. 0. 1. 0.]
# [0. 0. 0. 1.]]
y = np.count_nonzero(x)
print(y)
# 4
x = np.count_nonzero([[0,1,7,0,0],[3,0,0,2,19]])
print(x)
# 5
np.count_nonzero(x,axis=0) 表示求每一列中的非0元素
np.count_nonzero(x,axis=0) 表示求每一行中的非0元素
x = np.array([[0,1,7,0,0],[3,0,0,2,19]])
print(x)
# [[ 0 1 7 0 0]
# [ 3 0 0 2 19]]
y = np.count_nonzero(x)
print(y)
# 5
y = np.count_nonzero(x,axis=0)
print(y)
# [1 1 1 1 1]
y = np.count_nonzero(x,axis=1)
print(y)
# [2 3]
集合操作
构建集合 np.unique()
numpy.unique(x,return_index = False, return_inverse = True , return_counts = False)
numpy.unique() 构造一个集合,即删除掉x中的重复元素
x = np.unique([1,1,3,2,3,3])
print(x)
print(type(x))
# [1 2 3]
# <class 'numpy.ndarray'>
x = sorted(set([1,1,3,2,3,3]))
print(x)
print(type(x))
# [1, 2, 3]
# <class 'list'>
x = np.array([[1,1],[2,3]])
u = np.unique(x)
print(u)
# [1 2 3]
可以指定在哪个纬度构建集合
x = np.array([[1,0,0],[1,0,0],[2,3,4]])
print(x)
y = np.unique(x,axis=0)
print(y)
# [[1 0 0]
# [1 0 0]
# [2 3 4]]
# [[1 0 0]
# [2 3 4]]
return_index = True 表示 新列表元素在旧列表的位置
x = np.array(['a','a','c','b','b'])
# 新列表元素在旧列表的位置
u,index = np.unique(x,return_index=True)
print(u)
print(index)
print(x[index])
# ['a' 'b' 'c']
# [0 3 2]
# ['a' 'b' 'c']
return_inverse=True 表示 旧列表元素在新列表中的位置
x = np.array([1,1,6,4,2,3,2])
# 旧列表元素在新列表中的位置
u,index = np.unique(x,return_inverse=True)
print(u)
print(index)
print(u[index])
# [1 2 3 4 6]
# [0 0 4 3 1 2 1]
# [1 1 6 4 2 3 2]
return_counts=True 新列表元素在就列表中出现的次数
x = np.array([1,1,6,4,2,3,2])
u,count = np.unique(x,return_counts=True)
print(u)
# 新列表元素在就列表中出现的次数
print(count)
# [1 2 3 4 6]
# [2 2 1 1 1]
布尔运算 numpy.in1d()
np.in1d(x,y,invert=False) x中每一个元素是否在y中,返回布尔值组成的数组
invert表示是否取反
invert=True时表示对结果取反,即x中每一个元素是否不在y中
test = np.array([0,1,2,5,0])
states = [0,2]
mask = np.in1d(test,states)
print(mask)
# [ True False True False True]
print(test[mask])
# [0 2 0]
invert=True时表示对结果取反,即x中每一个元素是否不在y中
mask = np.in1d(test,states,invert=True)
print(mask)
# [False True False True False]
print(test[mask])
# [1 5]