Python数据分析库-Numpy库在数据分析中的知识点(三)
各位客官姥爷好,欢迎回来。上节我们了解了numpy数组的属性以及浅拷贝和深拷贝,这节我们来看看数组的其他用法。
01
改变数组的维度
0. 声明一个numpy的数组
x = np.random.randint(1,10,(3,4))
x
array([[6, 3, 5, 8],
[7, 9, 9, 2],
[7, 8, 8, 9]])
1. 改为一维数组
这里有两种方法:
1)flatten( order='C' )方法
y = x.flatten()
print(y)
y[0] = 1
print(y)
print(x)
[6 3 5 8 7 9 9 2 7 8 8 9]
[1 3 5 8 7 9 9 2 7 8 8 9]
[[6 3 5 8]
[7 9 9 2]
[7 8 8 9]]
2)ravel([order])方法
y = x.ravel()
print(y)
y[0] = 1
print(y)
print(x)
[6 3 5 8 7 9 9 2 7 8 8 9]
[1 3 5 8 7 9 9 2 7 8 8 9]
[[1 3 5 8]
[7 9 9 2]
[7 8 8 9]]
这里特别注意,当使用ravel时,修改新对象的值,源对象的值也会改变。
2. 改为其他维数的数组
这里同样有两种方法:
1)reshape( shape , order='C' ) 方法
x = np.random.randint(1,10,(2,6))
print(x)
m = x.reshape((3,4))
print(m)
m[0,1] = 88
print(m)
print(x)
[[2 6 9 5 4 1]
[4 6 1 3 4 9]]
[[2 6 9 5]
[4 1 4 6]
[1 3 4 9]]
[[ 2 88 9 5]
[ 4 1 4 6]
[ 1 3 4 9]]
[[ 2 88 9 5 4 1]
[ 4 6 1 3 4 9]]
同样,需要注意:更改新对象的元素,源对象的也会改变。
2)resize( new_shape , refcheck=True )方法
resize方法直接在源数组上更改。
x = np.random.randint(1,10,(2,6))
print(x)
#在这里赋值给y,y直接返回None。
y = x.resize((3,4))
print(x)
print(y)
[[8 3 1 1 5 6]
[6 7 9 5 2 5]]
[[8 3 1 1]
[5 6 6 7]
[9 5 2 5]]
None
02
数组索引相关
1.根据索引取值
take(indices, axis=None, out=None, mode='raise')方法
x = np.random.randint(1,10,(2,6))
print(x)
y = x.take([[1,2],[7,8]])
print(y)
[[4 7 9 1 9 6]
[1 7 6 4 2 9]]
[[7 9]
[7 6]]
如果不使用axis参数的话,默认把数组展开成一维。
x = np.random.randint(1,10,(2,6))
print(x)
y = x.take([[1,2],[4,5]], axis=1)
print(y)
[[3 2 2 3 2 5]
[3 6 6 6 3 6]]
[[[2 2]
[2 5]]
[[6 6]
[3 6]]]
x = np.random.randint(1,10,(2,6))
print(x)
y = x.take([[1,2],[4,5]], axis=0)
print(y)
更改axis=0,直接报错超出范围
IndexError: index 2 is out of bounds for size 2
可修改mode参数来避免报错,有三种可选参数:{'raise', 'wrap', 'clip'}。
--raise表示抛出异常(默认)
--wrap表示索引超出范围对数据进行环绕,环绕也就是重复使用,一轮用完,第二轮接着上。
x = np.random.randint(1,10,(5,6))
print(x)
y = x.take([[1,2],[4,5]], axis=0,mode='wrap')
print(y)
[[4 4 9 6 6 7]
[1 8 6 2 6 7]
[7 9 8 6 4 3]
[4 3 6 5 2 6]
[9 4 6 9 5 2]]
[[[1 8 6 2 6 7]
[7 9 8 6 4 3]]
[[9 4 6 9 5 2]
[4 4 9 6 6 7]]]
--clip:表示超出下标的部分,全部用最后一个。
x = np.random.randint(1,10,(5,6))
print(x)
y = x.take([[1,2],[4,5]], axis=0,mode='clip')
print(y)
[[8 9 2 3 2 2]
[8 6 1 5 2 2]
[7 7 1 3 4 8]
[3 5 1 7 3 5]
[8 4 1 6 5 1]]
[[[8 6 1 5 2 2]
[7 7 1 3 4 8]]
[[8 4 1 6 5 1]
[8 4 1 6 5 1]]]
2.根据索引替换值
put(indices, values, mode='raise')方法
x = np.random.randint(1,10,(2,6))
print(x)
y = x.put([[1,2],[3,4]],-5,mode='clip')
print(x)
print(y)
[[3 4 4 5 2 7]
[3 6 5 2 6 5]]
[[ 3 -5 -5 -5 -5 7]
[ 3 6 5 2 6 5]]
None
需要特别留意的是:这里是直接在源对象上更改,赋值的话返回的结果会是None。
要说起来从源对象上直接更改,这里也可以使用切片用法。
x = np.random.randint(1,10,(2,6))
print(x)
x[0,:3:1] = 0
print(x)
x[0:4:1,1] = 10
print(x)
[[9 9 4 3 1 8]
[5 7 1 6 4 4]]
[[0 0 0 3 1 8]
[5 7 1 6 4 4]]
[[ 0 10 0 3 1 8]
[ 5 10 1 6 4 4]]
03
数组的排序
1. 对数组进行排序
sort(axis=-1,kind=None,order=None)用法
axis默认值是-1,表示沿最后一个轴排序。
kind有{'quicksort'、'mergesort'、'heapsort'、'stable'}四种可选排序算法:quicksort快排(默认),mergesort归并排序,heapsort堆排序,stable稳定排序。
x = np.random.randint(1,10,(2,6))
print(x)
y = x.sort(axis=1)
print(x)
print(y)
[[2 2 2 8 1 1]
[3 2 5 7 1 7]]
[[1 1 2 2 2 8]
[1 2 3 5 7 7]]
None
可以看到这里同样是直接更改源对象。如果不想直接更改源对象,有什么办法吗?我们接着往下看。
2. 返回排序的索引
argsort(axis=- 1, kind=None, order=None)方法
x = np.random.randint(1,10,(2,6))
print(x)
y = x.argsort()
print(y)
[[1 2 9 4 6 1]
[2 2 4 8 4 8]]
[[0 5 1 3 4 2]
[0 1 2 4 3 5]]
看到这里返回的索引,是不是对我们上面的提问有了些头绪:我们前面刚好又讲过take的用法(可以根据索引返回值)。思路有了,这就开干。
x = np.random.randint(1,10,(2,6))
print(x)
y = x.argsort(axis = 1)
print('******')
print(y)
z = x.take(y,axis = 1)
print('******')
print(z)
[[3 9 1 9 7 3]
[7 6 4 8 9 4]]
******
[[2 0 5 4 1 3]
[2 5 1 0 3 4]]
******
[[[1 3 3 7 9 9]
[1 3 9 3 9 7]]
[[4 7 4 9 6 8]
[4 4 6 7 8 9]]]
但结果有点出乎意料,相当于源数组的每行都使用了索引一次。那有没有按照轴返回数组的方法呢?还真有(首先,在这里需要感谢这些numpy的开发人员,满足我们的各种需求),具体用法是:
numpy.take_along_axis(arr, indices, axis)
arr参数就是数组,indices就是索引,话不多说开干。
x = np.random.randint(1,10,(2,6))
print(x)
y = x.argsort(axis = 1)
print('******')
print(y)
z = np.take_along_axis(x,y,axis = 1)
print('******')
print(z)
[[9 9 5 5 2 1]
[8 7 3 2 1 7]]
******
[[5 4 2 3 0 1]
[4 3 2 1 5 0]]
******
[[1 2 5 5 9 9]
[1 2 3 7 7 8]]
结果正确,over!
3. 按某些序列进行排序
np.lexsort(keys, axis=- 1)方法,注意ndarray没有lexsort方法。
这里的key加s,表示可以多个,以最后一个为第一排序依据。
x = np.array([1,2,2,3,4,6,6,7])
y = np.array([9,0,3,1,2,6,5,0])
np.lexsort((y,x))
通过结果可以看出,对x进行排序,如果x相同的部分,则以y为排序依据。
array([0, 1, 2, 3, 4, 6, 5, 7], dtype=int64)
4.搜索排序
searchsorted(v, side='left', sorter=None)方法
返回小于或等于v值的值的索引位置。
x = np.array([9,0,3,1,2,6,5,0])
x.searchsorted(3,side='right')
5
side中的right/left其实就相当于开区间还是闭区间。
以上就是本次的分享,欢迎各位客官姥爷关注我,方便您第一次时间收到【干货】!