- 导包
- Python List
- numpy.array
- 其他numpy.array的方法
- arange
- linspace
- random
- numpy.array的基本操作
- 基本属性
- numpy.array的数据访问
- reshape
- 合并操作
- 分割操作
- 运算
- Universal Functions
- 矩阵运算
- 向量和矩阵的运算
- 矩阵的逆
浅学了一点numpy,努力向机器学习方向学习!听了慕课老师的课总结一下,如有不对,请大佬指正! 导包
import numpy numpy.__version__ #查看版本号 ##我的版本号‘1.15.1’ import numpy as np #起别名为np np.__version__ #一样可以查看版本号Python List
L = [i for i in range(10)] L #[0, 1, 2, 3, 4, 5, 6, 7, 8, 9] L[4] #4 L[5] = 'Machine Learning' L #[0, 1, 2, 3, 4, 'Machine Lwarning ', 6, 7, 8, 9]
相对来说,下面这个效率更高一点
import array
arr = array.array('i',[i for i in range(10)]) #i:限制类型为整型
arr
#array('i', [0, 1, 2, 3, 4, 5, 6, 7, 8, 9])
arr[5] = 100
arr
#array('i', [0, 1, 2, 3, 4, 100, 6, 7, 8, 9])
arr[5] = 'Machine Learning'
#TypeError: an integer is required (got type str)
numpy.array
nparr=np.array([i for i in range(10)])
nparr
#array([0, 1, 2, 3, 4, 5, 6, 7, 8, 9])
nparr.dtype
#dtype('int32')
nparr[5]=5.0
#array([0, 1, 2, 3, 4, 5, 6, 7, 8, 9])
nparr[5]=5.005004 #numpy的array只接受整型,所以进行了隐式的类型转换,所以输出的还是5
#array([0, 1, 2, 3, 4, 5, 6, 7, 8, 9])
nparr2=np.array([1,2,3.3])
nparr2.dtype
#dtype('float64')
其他numpy.array的方法
#创建都是0的数组
np.zeros(10)
#array([0., 0., 0., 0., 0., 0., 0., 0., 0., 0.])
np.zeros(10).dtype
#dtype('float64')
np.zeros(10,dtype=int).dtype
#dtype('int32')
#都是1
np.ones(10)
#array([1., 1., 1., 1., 1., 1., 1., 1., 1., 1.])
np.full((3,5),1)
#array([[1, 1, 1, 1, 1],
# [1, 1, 1, 1, 1],
# [1, 1, 1, 1, 1]])
arange
[i for i in range(0,20,2)] #从0到20,步长为2 #[0, 2, 4, 6, 8, 10, 12, 14, 16, 18] [i for i in range(0,20,0.2)] #报错了,步长不能是浮点数 np.arange(0,20,2) #从0到20,步长为2 #array([ 0, 2, 4, 6, 8, 10, 12, 14, 16, 18]) np.arange(0,1,0.2) #可以是浮点数 array([0. , 0.2, 0.4, 0.6, 0.8])linspace
np.linspace(0,20,10) #在0到20的区间里等长的截除10个数,包括0和20这两个点random
np.random.randint(0,10) #生成0,10之间的随机数 # 7 np.random.randint(0,10,10) #生成0,10之间随机数组成的数组,取不到10 #array([2, 3, 8, 7, 4, 0, 0, 4, 5, 6]) np.random.randint(0,1,10) #全是0,取不到1 # array([0, 0, 0, 0, 0, 0, 0, 0, 0, 0])
有时候有必要把属性写出来,因为有时候可能会分不清哪个是哪个,比如
np.random.randint(4,8,10)
所以,写上会清楚一点
np.random.randint(4,8,size=10) # array([6, 7, 6, 7, 6, 7, 7, 7, 4, 5]) np.random.randint(4,8,size=(3,5)) #随机矩阵 #array([[4, 7, 4, 4, 5], # [4, 4, 7, 4, 6], # [5, 6, 7, 4, 7]])
还有一点,每次random出来的都不一样,有时候调试会很麻烦,所以用随机种子
np.random.seed(666) np.random.randint(4,8,size=(3,5)) #array([[4, 6, 5, 6, 6], # [6, 5, 6, 4, 5], # [7, 6, 7, 4, 7]]) np.random.seed(666) #如果是完全随机,就不用写666了,相当于给了他一个编号我觉得,下次拿的时候直接拿这个就ok了 np.random.randint(4,8,size=(3,5)) #array([[4, 6, 5, 6, 6], # [6, 5, 6, 4, 5], # [7, 6, 7, 4, 7]]) # 一样的
np.random.random() #生成随机的浮点数 0-1之间均匀分布的 np.random.random() #生成随机的浮点数 0-1之间均匀分布的 np.random.random((3,5)) np.random.normal() #符合均值为0,方差为1这样分布的随机浮点数 np.random.normal(10,100) #均值为10,方差为100 np.random.normal(0,1,(3,5)) #均值为0,方差为1,大小3*5的矩阵numpy.array的基本操作
import numpy as np x=np.arange(10) #小x #array([0, 1, 2, 3, 4, 5, 6, 7, 8, 9]) X=np.arange(15).reshape(3,5) #大X X #array([[ 0, 1, 2, 3, 4], # [ 5, 6, 7, 8, 9], # [10, 11, 12, 13, 14]])基本属性
x.ndim #x是一维数组 # 1 X.ndim #X是二维数组 # 2 x.size #10 X.size #15 X.shape #(3,5)numpy.array的数据访问
X #array([0, 1, 2, 3, 4, 5, 6, 7, 8, 9]) X[0] #0 X[-1] #9 X[0][0] #不建议 #0 X[(0,0)] #建议 #0 x[:5] #array([0, 1, 2, 3, 4]) x[::2] #从头访问到尾,步长为2 #array([0, 2, 4, 6, 8]) x[::-1] #逆序 #array([9, 8, 7, 6, 5, 4, 3, 2, 1, 0])
X #array([[ 0, 1, 2, 3, 4], # [ 5, 6, 7, 8, 9], # [10, 11, 12, 13, 14]]) X[:2,:3] #前两行,前三列 #array([[0, 1, 2], # [5, 6, 7]]) X[:2][:3] #先取出前两行,在从前两行中取出前三行 #array([[0, 1, 2, 3, 4], # [5, 6, 7, 8, 9]]) X[:2,::2] #访问前两行,然后访问这两行从头到尾,步长为2 #array([[0, 2, 4], # [5, 7, 9]]) X[::-1,::-1] #array([[14, 13, 12, 11, 10], # [ 9, 8, 7, 6, 5], # [ 4, 3, 2, 1, 0]]) X[0] #取第一行 #array([0, 1, 2, 3, 4]) X[:,0] #只取第一列 #array([ 0, 5, 10]) subX=X[:2,:3] #取前两行的前三列 subX #array([[0, 1, 2], # [5, 6, 7]]) #修改元素 subX[0,0]=100 subX #array([[100, 1, 2], # [ 5, 6, 7]]) X #X中也变化了 #array([[100, 1, 2, 3, 4], # [ 5, 6, 7, 8, 9], # [ 10, 11, 12, 13, 14]])
当修改元素时,发现X也变化了。当我们使用copy()函数时,就不会变化
subX=X[:2,:3].copy() #用copy函数 subX #array([[0, 1, 2], # [5, 6, 7]]) subX[0,0]=100 subX #array([[100, 1, 2], # [ 5, 6, 7]]) X #不会动到X #array([[ 0, 1, 2, 3, 4], # [ 5, 6, 7, 8, 9], # [10, 11, 12, 13, 14]])reshape
继续刚才的操作
x.shape #(10,) x.ndim #1 x.reshape(2,5) #两行五列 #array([[0, 1, 2, 3, 4], # [5, 6, 7, 8, 9]]) x.reshape(10,-1) #我只希望有10行,有多少列计算机算 #array([[0], # [1], # [2], # [3], # [4], # [5], # [6], # [7], # [8], # [9]]) x.reshape(2,-1) #再试试两行的 #array([[0, 1, 2, 3, 4], # [5, 6, 7, 8, 9]])合并操作
x=np.array([1,2,3])
y=np.array([3,2,1])
x是一个1 * 3的向量,y是一个1 * 3的向量,我现在想要一个1 * 6的
使用concatenate,但是只能处理维度相同的数组
np.concatenate([x,y]) #拼接
#array([1, 2, 3, 3, 2, 1])
z=np.array([666,666,666])
np.concatenate([x,y,z])
#array([ 1, 2, 3, 3, 2, 1, 666, 666, 666])
A=np.array([[1,2,3],
[3,2,1]])
np.concatenate([A,A]) #二维数组拼接
np.concatenate([A,A]) #二维数组拼接
1
np.concatenate([A,A]) #二维数组拼接
#array([[1, 2, 3],
# [3, 2, 1],
# [1, 2, 3],
# [3, 2, 1]])
np.concatenate([A,A],axis=1) #沿着列的方向拼接 2行6列
#array([[1, 2, 3, 1, 2, 3],
# [3, 2, 1, 3, 2, 1]])
np.concatenate([A,A],axis=0) #沿着行的方向拼接 4行3列
假如维度不同呢
解决办法,把z转换1 * 3的
z=np.array([666,666,666]) np.concatenate([A,z]) #concatenate只能处理维度相同的数组 #ValueError: all the input arrays must have same number of dimensions #解决办法,把z转换1 * 3的 A2=np.concatenate([A,z.reshape(1,-1)]) #array([[ 1, 2, 3], # [ 3, 2, 1], # [666, 666, 666]])
堆叠数据,vstack和hstack
np.vstack([A,z]) #在垂直方向 将数据叠在一起 ,即使维度是不同的 #array([[ 1, 2, 3], # [ 3, 2, 1], # [666, 666, 666]]) B=np.full((2,2),100) B #array([[100, 100], # [100, 100]]) np.hstack([A,B]) #在水平方向 将数据叠在一起 ,即使维度是不同的 #array([[ 1, 2, 3, 100, 100], # [ 3, 2, 1, 100, 100]])分割操作
x=np.arange(10) x #array([0, 1, 2, 3, 4, 5, 6, 7, 8, 9])
分割
一维数组
x1,x2,x3=np.split(x,[3,7]) #分成3段 x1,x2,x3 #(array([0, 1, 2]), array([3, 4, 5, 6]), array([7, 8, 9])) x1,x2=np.split(x,[5]) #分成两段 #(array([0, 1, 2]), array([3, 4, 5, 6]))
二维数组
A=np.arange(16).reshape((4,4)) A #array([[ 0, 1, 2, 3], # [ 4, 5, 6, 7], # [ 8, 9, 10, 11], # [12, 13, 14, 15]])
分割
A1,A2=np.split(A,[2]) A1 #array([[0, 1, 2, 3], # [4, 5, 6, 7]]) A2 #array([[ 8, 9, 10, 11], # [12, 13, 14, 15]]) A1,A2=np.split(A,[2],axis=1) #axis=1按列分割,axis=0按行分割 A1 #array([[ 0, 1], # [ 4, 5], # [ 8, 9], # [12, 13]])
也可以这样
upper,lower=np.vsplit(A,[2]) #垂直方向分割 upper #array([[0, 1, 2, 3], # [4, 5, 6, 7]]) lower #array([[ 8, 9, 10, 11], # [12, 13, 14, 15]]) left,right=np.hsplit(A,[2]) #水平方向分割 left #array([[ 0, 1], # [ 4, 5], # [ 8, 9], # [12, 13]]) data=np.arange(16).reshape((4,4)) data #array([[ 0, 1, 2, 3], # [ 4, 5, 6, 7], # [ 8, 9, 10, 11], # [12, 13, 14, 15]]) 在机器学习中,一班最后一列是label,需要把他分开 X,y=np.hsplit(data,[-1]) X #array([[ 0, 1, 2], # [ 4, 5, 6], # [ 8, 9, 10], # [12, 13, 14]]) y #array([[ 3], # [ 7], # [11], # [15]]) y[:,0] #array([ 3, 7, 11, 15])运算
n=1000000
L=[i for i in range(n)]
L
#[0, 1, 2, 3, 4, 5, 6, 7, 8, 9]
想要输出2倍怎么算?
2*L
#[0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9]
不是
可以这样
A=[]
for e in L:
A.append(e*2)
A
#[0, 2, 4, 6, 8, 10, 12, 14, 16, 18]
在来看看时间消耗
%%time
A=[]
for e in L:
A.append(e*2)
#Wall time: 328 ms
#法二
%%time
A=[2*e for e in L]
#Wall time: 211 ms
#在numpy中
%%time
A=np.array(2*e for e in L)
#Wall time: 129 ms
%%time
A=2*L #numpy中支持这么写
Universal Functions
X=np.arange(1,16).reshape((3,5)) X #array([[ 1, 2, 3, 4, 5], # [ 6, 7, 8, 9, 10], # [11, 12, 13, 14, 15]]) X+1 #array([[ 2, 3, 4, 5, 6], # [ 7, 8, 9, 10, 11], # [12, 13, 14, 15, 16]]) X-1 X*2 X//2 x**2 1/x np.abs(x) np.sin(X) np.cos(X) np.tan(X) np.exp(X) #求e的x次幂 np.power(3,x) #求3的多少次方 np.log(X) #以e为底 np.log2(X) #以2为底矩阵运算
A=np.arange(4).reshape(2,2) A #array([[0, 1], # [2, 3]]) B=np.full((2,2),10) B #array([[10, 10], # [10, 10]]) A+B #array([[10, 11], # [12, 13]]) A-B #array([[-10, -9], # [ -8, -7]]) A*B #不是矩阵的乘法,是对应数做的运算 #array([[ 0, 10], # [20, 30]]) A.dot(B) #矩阵的乘法 #array([[10, 10], # [50, 50]]) A.T#转置 #array([[0, 2], # [1, 3]])向量和矩阵的运算
v=np.array([1,2])
V
#array([1, 2])
A
#array([[0, 1],
[2, 3]])
v+A
#array([[0, 1],
# [2, 3]])
np.vstack([v]*A.shape[0]) #对v垂直堆叠
#array([[1, 2],
# [1, 2]])
np.hstack([v]*A.shape[0]) #对v水平堆叠
#array([1, 2, 1, 2])
np.vstack([v]*A.shape[0]) +A
#array([[1, 3],
# [3, 5]])
np.tile(v,(2,1)) #堆叠,行向量堆叠两次,列向量堆叠一次
#array([[1, 2],
# [1, 2]])
v*A
#array([[0, 2],
# [2, 6]])
v.dot(A)
#array([4, 7])
A.dot(v) #看着不能乘,但是 A:2 * 2;v:1 * 2。dot函数会自动判断是用行还是用列,所以这个是把v看成两行一列
矩阵的逆
A #array([[0, 1], # [2, 3]]) #逆矩阵 invA=np.linalg.inv(A) #array([[-1.5, 0.5], # [ 1. , 0. ]]) A.dot(invA) #原矩阵乘逆矩阵=单位矩阵 #array([[1., 0.], # [0., 1.]]) invA.dot(A) #还是单位矩阵 #array([[1., 0.], # [0., 1.]]) X=np.arange(16).reshape(2,8) X #array([[ 0, 1, 2, 3, 4, 5, 6, 7], # [ 8, 9, 10, 11, 12, 13, 14, 15]]) np.linalg.inv(X) #LinAlgError: Last 2 dimensions of the array must be square #只有方阵才有逆矩阵 pinvX=np.linalg.pinv(X) #伪逆矩阵,因为只有方阵才有逆矩阵 #array([[-1.35416667e-01, 5.20833333e-02], # [-1.01190476e-01, 4.16666667e-02], # [-6.69642857e-02, 3.12500000e-02], # [-3.27380952e-02, 2.08333333e-02], # [ 1.48809524e-03, 1.04166667e-02], # [ 3.57142857e-02, -1.04083409e-17], # [ 6.99404762e-02, -1.04166667e-02], # [ 1.04166667e-01, -2.08333333e-02]]) pinvX.shape #(8, 2) X.dot(pinvX) #还是单位阵 #array([[ 1.00000000e+00, -2.49800181e-16], # [ 0.00000000e+00, 1.00000000e+00]])



