Python

笔记:python之 _Numpy的常用操作

2019-11-11  本文已影响0人  南有妖尾

一、Numpy

Numpy是一个多维数组对象,称为ndarray。其由两部分组成,一部分是实际的数据,另一部分是描述这些数据的元数据。

Numpy可以对数组结构数据进行运算,不用遍历循环,拥有随机数,线性代数,博里叶变换等功能。


numpy知识点总结表.png

1.1Numpy基础数据结构

1.1.1Numpy数组基础

import numpy as np #导入numpy包
ar=np.array([1,2,3,4]) #一维数组
print(ar,type(ar))
print(ar.ndim)
# ar.ndim 查看数组的轴数,轴数是指维度数

返回结果:

[1 2 3 4] <class 'numpy.ndarray'>
1
ar=np.array([[1,2,3],[4,5,6]]) #二维数组,2行3列
print(ar.ndim)
print(ar.shape)
# ar.shape 查看数组的结构,shape为(n,m),是n行m列的数组

返回结果:

2
#返回二维数组
(2, 3)
#返回结果是2行3列数组
ar=np.array([[1,2,3],[4,5,6]]) #二维数组,2行3列
print(ar.size)
#ar.size 查看数组内元素的总个数
#对于n行m列的数组,元素总数为n*m

返回结果:

6
ar1=np.array([[1,2,3],[4,5,6]])
print(type(ar1),ar1.dtype)
ar2=np.array([[1.0,2.2,3.4],[4.1,5.0,6.0]])
print(type(ar2),ar2.dtype)
#type()查看数组类型
#ar.dtype 查看数组元素的类型

返回结果:

<class 'numpy.ndarray'> int64
<class 'numpy.ndarray'> float64
ar1=np.array([[1,2,3],[4,5,6]])
ar2=np.array([[1.0,2.2,3.4],[4.1,5.0,6.0]])
print(ar1.itemsize) 
print(ar2.itemsize)
# 数组中每个元素的字节大小,int64类型字节为8,float64的字节为8
print(ar1.data,ar2.data)     
# 包含实际数组元素的缓冲区,由于一般通过数组的索引获取元素,所以通常不需要使用这个属性。

返回结果:

8
8
<memory at 0x2aae5df07a68> <memory at 0x2aae5df07b40>

1.1.2创建Numpy数组

ar1=np.array(range(10))  # 一维数组
ar2=np.array(list(range(5))) # 一维数组
ar3=np.array([[1,2,3],[4,5,6]])  # 二维数组
print(ar1,type(ar1))
print(ar2,type(ar2))
print(ar3,type(ar3),ar3.ndim,ar3.shape)

返回结果:

[0 1 2 3 4 5 6 7 8 9] <class 'numpy.ndarray'>
[0 1 2 3 4] <class 'numpy.ndarray'>
[[1 2 3]
 [4 5 6]] <class 'numpy.ndarray'> 2 (2, 3)
#arange()的用法与生成器range()一样
#arange()生成的数组均为一维数组
ar1=np.arange(10) 
#返回0-9,一共10个整数
ar2=np.arange(1,5) 
#返回1-4
ar3=np.arange(5,11,2) 
#返回5-10,步长为2
ar4=np.arange(5.0) 
#返回的是浮点型
print(ar1)
print(ar2)
print(ar3)
print(ar4)

返回结果:

[0 1 2 3 4 5 6 7 8 9]
[1 2 3 4]
[5 7 9]
[0. 1. 2. 3. 4.]
ar1=np.linspace(1,5)
#均匀返回范围在[1,5]之间的数组,元素个数默认为50
ar2=np.linspace(1,10,num=5)
#均匀返回范围在[1,10]之间的数组,元素个数为num=5个
ar3=np.linspace(1,10,num=8)
ar4=np.linspace(1,10,num=8,endpoint=False)
#参数endpoint默认为True,这时返回数组的最后一个元素=停止
#参数endpoint=False,这时返回数组的最后一个元素≠停止
ar5=np.linspace(1,10,num=5,retstep=True)
#参数restep=True,这时返回的是一个包含2个元素的元祖,第一个元素为array,第二个为步长实际值
print(ar1)
print(ar2)
print(ar3)
print(ar4)
print(ar5)

返回结果:

[1.         1.08163265 1.16326531 1.24489796 1.32653061 1.40816327
 1.48979592 1.57142857 1.65306122 1.73469388 1.81632653 1.89795918
 1.97959184 2.06122449 2.14285714 2.2244898  2.30612245 2.3877551
 2.46938776 2.55102041 2.63265306 2.71428571 2.79591837 2.87755102
 2.95918367 3.04081633 3.12244898 3.20408163 3.28571429 3.36734694
 3.44897959 3.53061224 3.6122449  3.69387755 3.7755102  3.85714286
 3.93877551 4.02040816 4.10204082 4.18367347 4.26530612 4.34693878
 4.42857143 4.51020408 4.59183673 4.67346939 4.75510204 4.83673469
 4.91836735 5.        ]
[ 1.    3.25  5.5   7.75 10.  ]
[ 1.          2.28571429  3.57142857  4.85714286  6.14285714  7.42857143  8.71428571 10.        ]
[1.    2.125 3.25  4.375 5.5   6.625 7.75  8.875]
(array([ 1.  ,  3.25,  5.5 ,  7.75, 10.  ]), 2.25)
#np.zeros()
ar1=np.zeros(5) #创建5个元素的一维数组,用0填充
print(ar1)
ar2=np.zeros((2,4)) #创建2行5列的二维数组,用0填充
print(ar2)
ar3=np.zeros((2,3),dtype=np.int)
#参数dtype:设置数组元素的数据类型,np.zeros()默认生成的数组元素为float
#这里设置为整数型
print(ar3,ar3.dtype)

#np.zeros_like()
ar4=np.array(list([[1,2,3],[4,5,6]])) 
#二维数组
print(ar4,ar4.ndim,ar4.shape)
#用np.zeros_like()可以生成一个与ar4结构相似,但系用0填充的数组
ar5=np.zeros_like(ar4)
print(ar5,ar5.ndim,ar5.shape)

返回结果:

[ 0.  0.  0.  0.  0.]
[[ 0.  0.  0.  0.]
 [ 0.  0.  0.  0.]]
[[0 0 0]
 [0 0 0]] int32
[[1 2 3]
 [4 5 6]] 2 (2, 3)
[[0 0 0]
 [0 0 0]] 2 (2, 3)
ar1=np.ones(5)
print(ar1)
ar2=np.ones((2,3),dtype=int)
print(ar2)
ar3=np.array(list([[1,2,3,4],[5,6,7,8]]))
print(ar3,ar3.shape)
ar4=np.ones_like(ar3)
print(ar4,ar4.shape)

返回结果:

[ 1.  1.  1.  1.  1.]
[[1 1 1]
 [1 1 1]]
[[1 2 3 4]
 [5 6 7 8]] (2, 4)
[[1 1 1 1]
 [1 1 1 1]] (2, 4)
ar=np.eye(5)
print(ar)

返回结果:

[[ 1.  0.  0.  0.  0.]
 [ 0.  1.  0.  0.  0.]
 [ 0.  0.  1.  0.  0.]
 [ 0.  0.  0.  1.  0.]
 [ 0.  0.  0.  0.  1.]]

1.2Numpy通用函数

1.2.1Numpy数组的形状(结构)

ar1=np.arange(10) 
#ar1一维数组
print(ar1,ar1.ndim,ar1.shape)
ar2=np.zeros((3,4))
#ar2二维数组
print(ar2,ar2.ndim,ar2.shape)
print('-----------')
#用 .T转置数组,例如原shape为(3,4)/(2,3,4),转置结果为(4,3)/(4,3,2)
#用 .T转置一维数组,一维数组转置后结果不变
ar3=ar1.T
ar4=ar2.T
print(ar3,ar3.ndim,ar3.shape)
print(ar4,ar4.ndim,ar4.shape)

返回结果:

[0 1 2 3 4 5 6 7 8 9] 1 (10,)
[[ 0.  0.  0.  0.]
 [ 0.  0.  0.  0.]
 [ 0.  0.  0.  0.]] 2 (3, 4)
-----------
[0 1 2 3 4 5 6 7 8 9] 1 (10,)
[[ 0.  0.  0.]
 [ 0.  0.  0.]
 [ 0.  0.  0.]
 [ 0.  0.  0.]] 2 (4, 3)
#①直接改变已有原数组的形状
ar1=np.zeros((4,4),dtype=int)
print(ar1)
ar2=ar1.reshape(2,8)
# 直接改变原ar1数组的形状,由4*4改变为2*8
print(ar2)
print('----------')
#②生成数组后,直接改变形状
ar2=np.array(list(range(10))).reshape(2,5)
# 这里先生成数组[0,1,2,3,4,5,6,7,8,9],是一维数组
# 用.reshape(shape)直接改变其形状
print(ar2)
print('-----------')
#③在.reshape()方法中的参数内添加数组、目标形状 等参数
ar3=np.reshape(np.array(list(range(12))),(3,4))
ar4=np.reshape(np.arange(10),(2,5))
print(ar3,ar3.shape)
print(ar4,ar4.shape)
# 日常创建二维数组,可以使用以上方法②③,更加方便

返回结果:

[[0 0 0 0]
 [0 0 0 0]
 [0 0 0 0]
 [0 0 0 0]]
[[0 0 0 0 0 0 0 0]
 [0 0 0 0 0 0 0 0]]
----------
[[0 1 2 3 4]
 [5 6 7 8 9]]
-----------
[[ 0  1  2  3]
 [ 4  5  6  7]
 [ 8  9 10 11]] (3, 4)
[[0 1 2 3 4]
 [5 6 7 8 9]] (2, 5)
ar=np.resize(np.arange(10),(3,4))
print(ar)
# np.resize()生成一个指定元素N个的数组
# 而生成的形状n行m列,n*m≠N,是ok的
# 因为n*m≠N,当n*m>N的时候,有必要可重复利用指定元素填充形状以达到足够
ar2=np.resize(np.arange(10),(2,4))
print(ar2)
# 当n*m<N的时候,可以不将指定元素全部使用填充在形状中

返回结果:

[[0 1 2 3]
 [4 5 6 7]
 [8 9 0 1]]
[[0 1 2 3]
 [4 5 6 7]]

【注意】 .T/.reshape()/.resize()都是生成新的数组!!!

1.2.2Numpy数组的复制

同样与list的复制方法一样,原理也是一样的,使用方法.copy()复制数组

1.2.3Numpy数组内元素的数据类型转换

用 .astype(),改变数组内元素的数据类型

ar=np.reshape(np.arange(10),(2,5))
print(ar,ar.dtype)
ar2=ar.astype(np.float64)
print(ar2,ar2.dtype)
#用 .astype()改变数组内元素的数据类型
#在改变数据类型的时候,括号内填写的数据类型最好填写np.int32、np.int64、np.float32、np.float64

返回结果:

[[0 1 2 3 4]
 [5 6 7 8 9]] int32
[[ 0.  1.  2.  3.  4.]
 [ 5.  6.  7.  8.  9.]] float64

1.2.4Numpy数组堆叠

# 水平堆叠
# np.hstack(tup):水平(按列顺序)堆叠数组
# np.hstack(tup)即系不增加数据量(行数),增加标签量(列数)
ar1=np.arange(10)
ar2=np.arange(5)
print(ar1)
print(ar2)
#将2个形状不一样的一维数组水平堆叠
print(np.hstack((ar1,ar2)))
print('----------')
ar3=np.reshape(np.arange(10),(2,5))   
ar4=np.reshape(np.arange(11,21),(2,5))
print(ar3)
print(ar4)
#将2个形状一致的二维数组水平堆叠
#将二维数组水平堆叠,要保证这些数组的形状一致
print(np.hstack((ar3,ar4)),np.hstack((ar3,ar4)).shape)

返回结果:

[0 1 2 3 4 5 6 7 8 9]
[0 1 2 3 4]
[0 1 2 3 4 5 6 7 8 9 0 1 2 3 4]
----------
[[0 1 2 3 4]
 [5 6 7 8 9]]
[[11 12 13 14 15]
 [16 17 18 19 20]]
[[ 0  1  2  3  4 11 12 13 14 15]
 [ 5  6  7  8  9 16 17 18 19 20]] (2, 10)
# np.stack(arrays, axis=0),沿着新轴连接数组的序列,形状必须一样!
# np.stack(arrays,axis=0)即系让数组垂直堆叠,按行顺序堆叠,增加行数→数量增加,标签量(列)不增加
#一维数组的垂直堆叠,垂直堆叠不管是一维数组或二维数组,形状必须一样
ar1=np.arange(6)
ar2=np.arange(7,13)
print(ar1,ar1.shape)
print(ar2,ar2.shape)
ar3=np.stack((ar1,ar2))
ar4=np.stack((ar1,ar2),axis=1)
# 参数axis默认为0,当axis=1时,shape置换了
print(ar3,ar3.shape)
print(ar4,ar4.shape)
print('------------')
# 二维数组垂直堆叠,形状也要一致
# 二维数组垂直堆叠,最后结果返回的数组为三维数组
ar1=np.reshape(np.arange(6),(2,3))
ar2=np.reshape(np.arange(7,13),(2,3))
print(ar1,ar1.shape)
print(ar2,ar2.shape)
ar3=np.stack((ar1,ar2))
print(ar3,ar3.shape,ar3.ndim)

返回结果:

[0 1 2 3 4 5] (6,)
[ 7  8  9 10 11 12] (6,)
[[ 0  1  2  3  4  5]
 [ 7  8  9 10 11 12]] (2, 6)
[[ 0  7]
 [ 1  8]
 [ 2  9]
 [ 3 10]
 [ 4 11]
 [ 5 12]] (6, 2)
------------
[[0 1 2]
 [3 4 5]] (2, 3)
[[ 7  8  9]
 [10 11 12]] (2, 3)
[[[ 0  1  2]
  [ 3  4  5]]

 [[ 7  8  9]
  [10 11 12]]] (2, 2, 3) 3

1.2.5Numpy数组拆分

# np.hsplit(ary, indices_or_sections)按列拆分,即按标签拆分
ar=np.reshape(np.arange(12),(2,6))
print(ar)
ar1=np.hsplit(ar,6)
# 参数indices_or_sections表示按n列拆分,即系拆分的标准
print(ar1,type(ar1))
# 数组拆分后,返回的结果类型为列表,列表中嵌套折数组

返回结果:

[[ 0  1  2  3  4  5]
 [ 6  7  8  9 10 11]]
[array([[0],
       [6]]), array([[1],
       [7]]), array([[2],
       [8]]), array([[3],
       [9]]), array([[ 4],
       [10]]), array([[ 5],
       [11]])] <class 'list'>
# np.vsplit(ary, indices_or_sections),按行拆分,将数组垂直(按行方向)拆分为多个子数组
ar=np.reshape(np.arange(12),(2,6))
print(ar,ar.shape)
ar1=np.vsplit(ar,2)
# # 参数indices_or_sections同样表示按N行拆分,即系拆分的标准
print(ar1)

返回结果:

[[ 0  1  2  3  4  5]
 [ 6  7  8  9 10 11]] (2, 6)
[array([[0, 1, 2, 3, 4, 5]]), array([[ 6,  7,  8,  9, 10, 11]])]

1.2.6Numpy数组的简单运算

ar = np.arange(6).reshape(2,3)
print(ar)
print('--------')
print(ar + 10)   # 加法
print('--------')
print(ar * 2)   # 乘法
print('--------')
print(1 / (ar+1))  # 除法
print('--------')
print(ar ** 0.5)  # 幂

返回结果:

[[0 1 2]
 [3 4 5]]
--------
[[10 11 12]
 [13 14 15]]
--------
[[ 0  2  4]
 [ 6  8 10]]
--------
[[ 1.          0.5         0.33333333]
 [ 0.25        0.2         0.16666667]]
--------
[[ 0.          1.          1.41421356]
 [ 1.73205081  2.          2.23606798]]
ar=np.reshape(np.arange(12),(3,4))
print(ar)
#常用函数
print(ar.mean()) # 求平均值
print(ar.max()) # 求最大值
print(ar.min()) # 求最小值
print(ar.var()) # 求方差
print(ar.std()) # 求标准差

#求和
print(ar.sum()) # 整体求和
print(np.sum(ar,axis=0)) # axis为0,按标签(列)求和
print(np.sum(ar,axis=1)) # axis为1,按行求和

#排序 np.sort(arr) 默认升序排列
ar1=np.array(list([33,1,54,6,7,8,123]))
print(ar1)
print(np.sort(ar1))

返回结果:

[[ 0  1  2  3]
 [ 4  5  6  7]
 [ 8  9 10 11]]
5.5
11
0
11.9166666667
3.45205252953
66
[12 15 18 21]
[ 6 22 38]
[ 33   1  54   6   7   8 123]
[  1   6   7   8  33  54 123]

1.3Numpy索引及切片

1.3.1一维数组的索引及切片

# 一维数组的索引、切片
ar=np.arange(10)
print(ar)
print(ar[2]) # 索引:返回索引为2的值
print(ar[0:3]) # 切片:返回索引为0-2的值

返回结果:

[0 1 2 3 4 5 6 7 8 9]
2
[0 1 2]

1.3.2二维数组的索引及切片

# 二维数组的索引、切片
# 索引
ar=np.reshape(np.arange(12),(3,4))
print(ar)
print('------')
print(ar[1])
# 索引二维数组某行:2种写法
# 索引:返回第2行,一维数组
print(ar[0][2])
print(ar[0,2])
# 索引二维数组的某个值
# 索引:ar[0][2]→返回第一行,第三列的值
# 二维数组通过二次索引,得到一维数组中的一个值
# 二维数组第一个索引为行,第二个索引为列
print('--------')

# 切片
print(ar[0:2])
# 切片:返回第1行-第2行的数组
print(ar[:2,:3])
# 切片:返回第0-2行,第0-2列的二维数组

返回结果:

[[ 0  1  2  3]
 [ 4  5  6  7]
 [ 8  9 10 11]]
------
[4 5 6 7]
2
2
--------
[[0 1 2 3]
 [4 5 6 7]]
[[0 1 2]
 [4 5 6]]

1.3.3三维数组的索引及切片

ar = np.arange(8).reshape(2,2,2)
print(ar)   # 2*2*2的数组
print('------')
print(ar[0])  # 三维数组的下一个维度的第一个元素 → 一个二维数组
print('------')
print(ar[0][0])  # 三维数组的下一个维度的第一个元素下的第一个元素 → 一个一维数组
print('------')
print(ar[0][0][1]) 

返回结果:

[[[0 1]
  [2 3]]

 [[4 5]
  [6 7]]]
------
[[0 1]
 [2 3]]
------
[0 1]
------
1

1.3.4布尔型索引及切片

ar = np.arange(12).reshape(3,4)
i = np.array([True,False,True])
j = np.array([True,True,False,False])
print(ar)
print('------')
print(i)
print('------')
print(j)
print('------')
print('------')
# 布尔型索引:以布尔型的矩阵去做筛选
print(ar[i,:])
# 因为i的数组是[ True False  True],ar[i,:]表示从第一行到最后一行按照i规则筛选,只保留为True的值
print(ar[:,j])
# 同理,从第一列到最后一列按j规则筛选,指保留True值
print('------')
print('------')
# 数组做判断
m = ar > 5
print(m) 
# 这里m是一个判断矩阵
print(ar[m])
# 用m判断矩阵去筛选ar数组中>5的元素 → 重点!后面的pandas判断方式原理就来自此处

返回结果:

[[ 0  1  2  3]
 [ 4  5  6  7]
 [ 8  9 10 11]]
------
[ True False  True]
------
[ True  True False False]
------
------
[[ 0  1  2  3]
 [ 8  9 10 11]]
[[0 1]
 [4 5]
 [8 9]]
------
------
[[False False False False]
 [False False  True  True]
 [ True  True  True  True]]
[ 6  7  8  9 10 11]

1.3.5数组索引及切片的值更改

ar = np.arange(10)
print(ar)
ar[5] = 100
ar[7:9] = 200
print(ar)
# 一个标量赋值给一个索引/切片时,会自动改变/传播原始数组

返回结果:

[0 1 2 3 4 5 6 7 8 9]
[  0   1   2   3   4 100   6 200 200   9]

1.4Numpy随机数

numpy.random包含多种概率分布的随机样本,是数据分析辅助的重点工具之一。

# np.random.normal()生成标准正态分布的样本值
ar1=np.random.normal(size=(2,5))
# 生成一个2*5的标准正态分布随机数二维数组 
print(ar1,ar1.ndim)
ar2=np.random.normal(size=(10))
# 生成一个含10个随机数的标准正态分布的一维数组
print(ar2,ar2.ndim)

返回结果:

[[ 0.88655124  2.1149253   0.43741726 -0.53253323 -0.48869879]
 [-0.53169966  1.14165196 -0.69534573 -0.56528542  0.06384804]] 2
[ 0.62133117 -1.17322945 -0.59900353 -0.24797495 -1.47763584  0.17037937  -1.55065207  0.33064179  0.65875716 -0.94100423] 1

[图片上传失败...(image-67783e-1573461146112)]

正态分布

# np.random.rand(数量/shape)生成均匀分布的随机样本值,且随机值的取值范围在[0,1)之间的浮点数
a=np.random.rand()
# 括号内无参数,生成1个随机数
print(a)
b=np.random.rand(5)
print(b,type(b))
# 括号内参数5,表示生成5个随机元素的一维数组
c=np.random.rand(3,4)
# 括号内参数(3,4),表示生成形状为3*4的随机二维数组
print(c,type(c))

返回结果:

0.9016508427547637
[ 0.26493118  0.0704723   0.89982074  0.36608956  0.00578482] <class 'numpy.ndarray'>
[[ 0.43569007  0.13525582  0.76689353  0.6985516 ]
 [ 0.20385585  0.5892726   0.44935053  0.64982622]
 [ 0.38250811  0.91152112  0.01945527  0.87157172]] <class 'numpy.ndarray'>

[图片上传失败...(image-ddb0d3-1573461146112)]

均匀分布

# np.random.randint(low, high=None, size=None)生成整数随机数样本
# 若high不为None时,取[low,high)之间随机整数,否则取值[0,low)之间随机整数,且high必须大于low 
# 参数size表示取指定范围内随机整数的个数
a=np.random.randint(5)
print(a)
# 随机取[0,5)之间的随机整数一个

b=np.random.randint(5,11)
# 随机取[5,11)之间的随机整数一个
print(b)

c=np.random.randint(5,11,size=3)
# 随机取[5,11)之间的随机整数三个
print(c)

d=np.random.randint(6,13,size=(2,3))
# 随机取[6,13)之间的随机整数,且生成形状为2*3的二维数组
print(d)

返回结果:

3
9
[5 5 9]
[[7 7 8]
 [7 8 7]]

1.5Numpy数据的输入输出

# np.save()储存.npy文件
import os
os.chdir(r'C:\Users\Yeung\Desktop')
# 指定目录
ar=np.random.normal(size=(3,4))
print(ar)
np.save('test.npy',ar)
# np.save('文件名称.npy',arr)

返回结果:

[[-0.54397732 -1.09388488 -0.19746632  0.8985579 ]
 [ 1.36390726  2.0033022  -0.68155601 -0.82123667]
 [ 1.02390926 -0.25270019 -1.64947932 -1.34882138]]
 # 运行成功,会在指定的目录下生成 test.npy文件
ar_load=np.load('test.npy') #读取文件
print(ar_load)

返回结果:

[[-1.1105341   0.71617645  1.44667116 -0.30821313]
 [-0.37763176 -1.27954983  0.52480404  1.61004855]
 [ 0.36051318  0.20473897 -0.85958953 -1.19440192]]
# 存储/读取文本文件
ar = np.random.rand(5,5)
np.savetxt('array.txt',ar, delimiter=',')
# np.savetxt(fname, X, fmt='%.18e', delimiter=' ', newline='\n', header='', footer='', comments='# '):存储为文本txt文件
# 参数 fmt,表示数据存储的格式
# 参数 delimiter,表示数据储存时分隔符号
ar_loadtxt = np.loadtxt('array.txt', delimiter=',')
print(ar_loadtxt)
# 也可以直接 np.loadtxt('C:/Users/Hjx/Desktop/array.txt')

返回结果:

[[ 0.28280684  0.66188985  0.00372083  0.54051044  0.68553963]
 [ 0.9138449   0.37056825  0.62813711  0.83032184  0.70196173]
 [ 0.63438739  0.86552157  0.68294764  0.2959724   0.62337767]
 [ 0.67411154  0.87678919  0.53732168  0.90366896  0.70480366]
 [ 0.00936579  0.32914898  0.30001813  0.66198967  0.04336824]]

上一篇下一篇

猜你喜欢

热点阅读