初识numpy
简介
列表list: 元素可以是任何对象,因此列表中所保存的是对象的指针。
数组array: 不支持多维,也不适合数值计算。
Numpy:弥补了这些不足,提供了两种对象:ndarray和ufunc。ndarray是存储单一数据类型的多维数组,ufunc是能够对数组进行处理的函数。
生成Numpy数组
将列表转换为ndarray
import numpy as np
list1 = [[1,2,3,4,5],[6,7,8,9,10]]
nd_test = np.array(list1)#使用np.array进行转化
print(nd_test)
结果:
array([[ 1, 2, 3, 4, 5],
[ 6, 7, 8, 9, 10]])
注意点:在转换时,列表可以是多维的,但同一维度里的数据数量需要保持一致。
利用random模块生成数组
import numpy as np
nd4 = np.random.randn(2,3)#生成标准正态的随机数 2行3列
nd4
结果:
array([[ 0.20222822, -2.49432154, -0.22790614],
[ 1.70148951, -0.65704327, -1.94891589]])
创建特定形状的多维数组
import numpy as np
nd5 = np.zeros([3,3])#生成全为0的3*3矩阵
nd6 = np.ones([3,3])#生成全为1的3*3矩阵
nd7 = np.eye(3)#生成3*3单位矩阵
nd8 = np.diag([1,2,3])#生成三阶对角矩阵
print(nd5)
print(nd6)
print(nd7)
print(nd8)
结果:
[[0. 0. 0.]
[0. 0. 0.]
[0. 0. 0.]]
[[1. 1. 1.]
[1. 1. 1.]
[1. 1. 1.]]
[[1. 0. 0.]
[0. 1. 0.]
[0. 0. 1.]]
[[1 0 0]
[0 2 0]
[0 0 3]]
利用arange和linspace函数生成数组
import numpy as np
print(np.arange(10))
print(np.arange(0,10))
print(np.arange(1,4,0.5))
print(np.arange(9,-1,-1))
print(np.linspace(0,1,10))
结果:
[0 1 2 3 4 5 6 7 8 9]
[0 1 2 3 4 5 6 7 8 9]
[1. 1.5 2. 2.5 3. 3.5]
[9 8 7 6 5 4 3 2 1 0]
[0. 0.11111111 0.22222222 0.33333333 0.44444444 0.55555556
0.66666667 0.77777778 0.88888889 1. ]
获取元素
import numpy as np
np.random.seed(2019)
nd11 = np.random.random([10])
#获取指定位置的数据,获取第4个元素
nd11[3]
#截取一段数据
nd11[3:6]
#截取固定间隔数据
nd11[1:6:2]
#倒序取数
nd11[::-2]
#截取一个多维数组的一个区域内数据
nd12=np.arange(25).reshape([5,5])
nd12[1:3,1:3]
#截取一个多维数组中,数值在一个值域之内的数据
nd12[(nd12>3)&(nd12<10)]
#截取多维数组中,指定的行,如读取第2,3行
nd12[[1,2]] #或nd12[1:3,:]
##截取多维数组中,指定的列,如读取第2,3列
nd12[:,1:3]
结果:
0.6378774010222266
[0.6378774 0.88049907 0.29917202]
[0.39308051 0.6378774 0.29917202]
[0.4057498 0.90320616 0.29917202 0.6378774 0.39308051]
[[ 6 7]
[11 12]]
[4 5 6 7 8 9]
[[ 5 6 7 8 9]
[10 11 12 13 14]]
[[ 1 2]
[ 6 7]
[11 12]
[16 17]
[21 22]]
Numpy算数运算
对应元素相乘
A = np.array([[1,2],[-1,4]])
B = np.array([[2,0],[3,4]])
#对应位置相乘
A*B
np.multiply(A,B)
#结果array([[ 2, 0],
# [-3, 16]])
X = np.random.rand(2,3)
#激活函数
def softmoid(x):
return 1/(1+np.exp(-x))
def relu(x):
return np.maximum(0,x)
def softmax(x):
return np.exp(x)/np.sum(np.exp(x))
X.shape
#结果:(2,3)
点积运算
X1 = np.array([[1,2],[3,4]])
X2 = np.array([[5,6,7],[8,9,10]])
X3 = np.dot(X1,X2)#X1第二维和X2第一维保持一致
X3
结果:
array([[21, 24, 27],
[47, 54, 61]])
数组变形
更改数组形状
1.reshape
import numpy as np
#改变向量维度,不改变向量本身。
arr = np.arange(10)
print(arr)
#将arr维度变化为2行5列
print(arr.reshape(2,5))
#指定维度可以只指定行数或列数,其他用-1代替
print(arr.reshape(5,-1))
print(arr.reshape(-1,5))
结果:
[0 1 2 3 4 5 6 7 8 9]
[[0 1 2 3 4]
[5 6 7 8 9]]
[[0 1]
[2 3]
[4 5]
[6 7]
[8 9]]
[[0 1 2 3 4]
[5 6 7 8 9]]
**注意:reshape函数不支持指定函数或列数,所以-1在这里是必要的。**且所指的行数或列数一定要能被整除。
2.resize
import numpy as np
#改变向量维度,修改向量本身
arr = np.arange(10)
print(arr)
#将arr转换为2行5列
arr.resize(2,5)
print(arr)
结果:
[0 1 2 3 4 5 6 7 8 9]
[[0 1 2 3 4]
[5 6 7 8 9]]
3.T
import numpy as np
#向量转置
arr = np.arange(12).reshape(3,4)
print(arr)
#将向量arr转置
print(arr.T)
结果:
[[ 0 1 2 3]
[ 4 5 6 7]
[ 8 9 10 11]]
[[ 0 4 8]
[ 1 5 9]
[ 2 6 10]
[ 3 7 11]]
4.ravel
import numpy as np
#向量展平
arr = np.arange(6).reshape(2,-1)
print(arr)
#按列优先,展平
print('按列优先,展平')
print(arr.ravel('F'))
#按行优先,展平
print('按列行优先,展平')
print(arr.ravel())
结果:
[[0 1 2]
[3 4 5]]
按列优先,展平
[0 3 1 4 2 5]
按列行优先,展平
[0 1 2 3 4 5]
5.flatten
import numpy as np
#将矩阵转换为向量,通常出现在卷积网络与全连接层之间
a = np.floor(10*np.random.random((3,4)))#向下取整
print(a)
print(a.flatten())
结果:
[[5. 6. 0. 8.]
[0. 5. 5. 3.]
[8. 4. 1. 7.]]
[5. 6. 0. 8. 0. 5. 5. 3. 8. 4. 1. 7.]
6.squeeze
import numpy as np
#主要用来降维,把矩阵中含1的维度去掉
arr = np.arange(3).reshape(3,1)
print(arr)
print(arr.shape)
print(arr.squeeze())
print(arr.squeeze().shape)
arr1 = np.arange(6).reshape(3,1,2,1)
print(arr1)
print(arr1.shape)
print(arr1.squeeze().shape)
结果:
[[0]
[1]
[2]]
(3, 1)
[0 1 2]
(3,)
[[[[0]
[1]]]
[[[2]
[3]]]
[[[4]
[5]]]]
(3, 1, 2, 1)
(3, 2)
7.transpose
import numpy as np
#对高维矩阵进行轴对换
arr2 = np.arange(24).reshape(2,3,4)
print(arr2)
print(arr2.shape)
print(arr2.transpose(1,2,0))#将第二维移到第一维上,第三维移到第二维上。
print(arr2.transpose(1,2,0).shape)
结果:
[[[ 0 1 2 3]
[ 4 5 6 7]
[ 8 9 10 11]]
[[12 13 14 15]
[16 17 18 19]
[20 21 22 23]]]
(2, 3, 4)
[[[ 0 12]
[ 1 13]
[ 2 14]
[ 3 15]]
[[ 4 16]
[ 5 17]
[ 6 18]
[ 7 19]]
[[ 8 20]
[ 9 21]
[10 22]
[11 23]]]
(3, 4, 2)
合并数组
1.append
import numpy as np
#合并一维数组
a = np.array([1,2,3])
b = np.array([4,5,6])
c = np.append(a,b)
print(c)
结果:
[1 2 3 4 5 6]
import numpy as np
#合并多维数组
a = np.arange(4).reshape(2,2)
b = np.arange(4).reshape(2,2)
#按行合并
c = np.append(a,b,axis=0)
print('按行合并后的结果')
print(c)
print('合并后数据维度',c.shape)
#按列合并
d = np.append(a,b,axis=1)
print('按列合并后的结果')
print(d)
print('合并后数据维度',d.shape)
结果:
按行合并后的结果
[[0 1]
[2 3]
[0 1]
[2 3]]
合并后数据维度 (4, 2)
按列合并后的结果
[[0 1 0 1]
[2 3 2 3]]
合并后数据维度 (2, 4)
2.concatenate
import numpy as np
#沿指定方向连接数组或矩阵
a = np.array([[1,2],[3,4]])
b = np.array([[5,6]])
c = np.concatenate((a,b),axis=0)
print(c)
d = np.concatenate((a,b.T),axis=1)
print(d)
结果:
[[1 2]
[3 4]
[5 6]]
[[1 2 5]
[3 4 6]]
3.stack
import numpy as np
#沿指定轴堆叠数组或矩阵
a = np.array([[1,2],[3,4]])
b = np.array([[5,6],[7,8]])
print(np.stack((a,b),axis=0))
结果:
[[[1 2]
[3 4]]
[[5 6]
[7 8]]]
批量处理Mini-Batch
步骤:
1)得到数据集
2)随机打乱数据
3)定义批大小
4)批处理数据集
import numpy as np
#生成10000个形状为2*3的矩阵
data_train = np.random.randn(10000,2,3)
#这是一个3维矩阵,第1个维度为样本数,后两个是数据形状
print(data_train.shape)
#(10000,2,3)
#打乱这10000条数据
np.random.shuffle(data_train)
#定义批量大小
batch_size = 100
#进行预处理
for i in range(0,len(data_train),batch_size):
x_batch_sum = np.sum(data_train[i:i+batch_size])
print("第{}批次,该批次的数据之和:{}".format(i,x_batch_sum))
通用函数
1.math与numpy函数的性能比较
import time
import math
import numpy as np
x = [i*0.001 for i in np.arange(1000000)]
start = time.clock()
for i,t in enumerate(x):
x[i] = math.sin(t)
print("math.sin:",time.clock()-start)
x = [i*0.001 for i in np.arange(1000000)]
x = np.array(x)
start = time.clock()
np.sin(x)
print("numpy.sin:",time.clock()-start)
结果:
math.sin: 0.1313402000005226
numpy.sin: 0.009974299999157665
2.循环与向量运算比较
import time
import numpy as np
x1 = np.random.rand(1000000)
x2 = np.random.rand(1000000)
#使用循环计算向量点积
tic = time.process_time()
dot = 0
for i in range(len(x1)):
dot+= x1[i]*x2[i]
toc = time.process_time()
print("dot = "+ str(dot) + "\n for loop ---- Computation time ="+ str(1000*(toc-tic))+"ms")
#使用Numpy函数求点积
tic = time.process_time()
dot = 0
dot = np.dot(x1,x2)
toc = time.process_time()
print("dot = "+ str(dot) + "\n vector version---- Computation time ="+ str(1000*(toc-tic))+"ms")
结果:
dot = 250035.7146828224
for loop ---- Computation time =250.0ms
dot = 250035.71468282328
vector version---- Computation time =0.0ms
广播机制
import numpy as np
A = np.arange(0,40,10).reshape(4,1)
B = np.arange(0,3)
print('A矩阵的形状:{},B形状的形状:{}'.format(A.shape,B.shape))
C=A+B
print("C矩阵的形状:{}".format(C.shape))
print(C)
结果:
A矩阵的形状:(4, 1),B形状的形状:(3,)
C矩阵的形状:(4, 3)
[[ 0 1 2]
[10 11 12]
[20 21 22]
[30 31 32]]