大数据,机器学习,人工智能机器学习与数据挖掘机器学习与计算机视觉

机器学习系列(三)——Numpy数组与矩阵

2019-06-07  本文已影响0人  Ice_spring

Numpy.array基本操作

生成一个数组

import numpy as np
x=np.arange(10)
x
#out:array([0, 1, 2, 3, 4, 5, 6, 7, 8, 9])

生成一个矩阵

y=np.arange(15).reshape(3,5)
y
#out:
array([[ 0,  1,  2,  3,  4],
       [ 5,  6,  7,  8,  9],
       [10, 11, 12, 13, 14]])

基本属性

x.ndim查看x数据维度out:1
x.shape返回一个元组,查看具体大小out:(10,)
x.size返回x中数据个数out:10
y.ndim查看y数据维度out:2
y.shape返回一个元组,查看具体大小out:(3,5)
y.size返回y中数据个数out:15

array数据访问

方括号索引:x[2]out:2
参数为负数表示倒着数:x[-1]out9
若是矩阵只指定一个维度输出是行向量:
y[2]out:array([10, 11, 12, 13, 14])
若访问第0行第2个元素:
y[0][2]out:2但是这种方式不建议。
//或
y[0,2]out:2这种方式是numpy提供的方式,可加圆括号(0,2)。
两个方括号在索引切片时存在问题。
切片x[1:5]out:array([1, 2, 3, 4])不包含切片终端点元素。

x[:4]
#out:array([0, 1, 2, 3])
x[6:]
#out:array([6, 7, 8, 9])

第三个参数是切片步长:
x[ : : 2]out:array([0, 2, 4, 6, 8])
x[ : : -1]out:array([9, 8, 7, 6, 5, 4, 3, 2, 1, 0])
二维数组切片:
y[ : 2,: 3]取前两行的前三列out:

array([[0, 1, 2]
        ,[5, 6, 7]])

但是用两个方括号的切片就会出错:

y[:2][:3]
#out:array([[0, 1, 2, 3, 4],
       [5, 6, 7, 8, 9]])

因为首先解析切片y[:2],取了前两行,(y[:2])[:3]本意是取前三列,但是这里实际是取y[:2]的前三行。
组合切片
访问前两行从头到尾间隔为2元素:

y[ :2,: : 2]
#out:array([[0, 2, 4],
       [5, 7, 9]])

行倒着数,列也倒着数:

y[ : : -1,: : -1]
#out:array([[14, 13, 12, 11, 10],
       [ 9,  8,  7,  6,  5],
       [ 4,  3,  2,  1,  0]])

y[0]等价于y[0,:]取行,取列则不行,建议使用numpy方式。
与python中切片的不同:

suby=y[:2,:3]
suby
#out:array([[0, 1, 2],
       [5, 6, 7]])
suby[0,0]=100
suby
#out:array([[100,   1,   2],
       [  5,   6,   7]])
y
#out:array([[100,   1,   2,   3,   4],
       [  5,   6,   7,   8,   9],
       [ 10,  11,  12,  13,  14]])

可以看到对切片后子矩阵的元素做修改,切片被修改后,原矩阵也被修改。而python中list的切片是创建了一个全新的矩阵,修改不影响原矩阵。因为numpy优先考虑效率,取子矩阵得到的是原矩阵的一个引用。
如果要创建与原矩阵不相关的子矩阵,要使用copy方法:

suby=y[:2,:3].copy()
suby
#out:array([[0, 1, 2],
       [5, 6, 7]])

此时修改suby,y是没有被改变的。


reshape

reshape参数是元组,不过括号可以省略。这里x是有10个元素的一维向量。

x.reshape(2,5)
#out:array([[0, 1, 2, 3, 4],
       [5, 6, 7, 8, 9]])

reshape不改变原数组或矩阵。
二维数组与一维数组区别:

x#一维数组
#out:array([0, 1, 2, 3, 4, 5, 6, 7, 8, 9])
x.reshape(1,10)#二维数组
#out:array([[0, 1, 2, 3, 4, 5, 6, 7, 8, 9]])

我们可以让计算机帮助我们智能确定,比如:

x.reshape(2,-1)
#我只想要两行,至于每行几个元素我不关心
#out:array([[0, 1, 2, 3, 4],
       [5, 6, 7, 8, 9]])

x.reshape(-1,2)
#我只想要两列,至于每列几个元素我不关心
#out:array([[0, 1],
       [2, 3],
       [4, 5],
       [6, 7],
       [8, 9]])

但是无论是自动确定还是指定reshape必须保证整除关系。

合并操作

对数组的合并

x=np.array([1,2,3])
y=np.array([4,5,6])
#让x与y合并,获得一个1×6向量
np.concatenate([x,y])
#out:array([1, 2, 3, 4, 5, 6])

z=np.array([6,6,6])
np.concatenate([x,y,z])#支持多个参数
#out:array([1, 2, 3, 4, 5, 6, 6, 6, 6])

也可以对矩阵进行合并

A=np.array([[1,2,3],[4,5,6]])
np.concatenate([A,A])#会按行进行拼接
#out:array([[1, 2, 3],
       [4, 5, 6],
       [1, 2, 3],
       [4, 5, 6]])

可以理解为样本数量的增加。另一种是特征的增加:

A=np.array([[1,2,3],[4,5,6]])
np.concatenate([A,A],axis=1)
#out:array([[1, 2, 3, 1, 2, 3],
       [4, 5, 6, 4, 5, 6]])

axis默认为0,意思是沿着第一维度行方向进行操作,为1,则沿着第二维度方向拼接。
向量与矩阵的拼接:
concatenate只能处理同维数的矩阵拼接,比如拼接z和A
np.concatenate([A,z])会报错,当然可以将z整理形状后拼接:

np.concatenate([A,z.reshape(1,3)])
#out:array([[1, 2, 3],
       [4, 5, 6],
       [6, 6, 6]])

不过numpy中有更好的方法vstack和hstack:

np.vstack([A,z])
#out:array([[1, 2, 3],
       [4, 5, 6],
       [6, 6, 6]])

B=np.array([[1,2],[2,3]])
np.hstack([A,B])
#out:array([[1, 2, 3, 1, 2],
       [4, 5, 6, 2, 3]])

水平堆叠和竖直堆叠虽然能智能处理,但传入的也必须合法,否则会报错。

分割操作

split传入待分割数组和分割点列表

x=np.arange(10)
x
#out:array([0, 1, 2, 3, 4, 5, 6, 7, 8, 9])
np.split(x,[3,7])
#out:[array([0, 1, 2]), array([3, 4, 5, 6]), array([7, 8, 9])]

同样可以对矩阵进行分割,此时,axis默认为0,按行分割。

A=np.arange(16).reshape((4,4))
A
#out:array([[ 0,  1,  2,  3],
       [ 4,  5,  6,  7],
       [ 8,  9, 10, 11],
       [12, 13, 14, 15]])
A1,A2=np.split(A,[2])#分为两个部分
A1
out:array([[0, 1, 2, 3],
       [4, 5, 6, 7]])

A3,A4=np.split(A,[2],axis=1)#按列
A3
#out:array([[ 0,  1],
       [ 4,  5],
       [ 8,  9],
       [12, 13]])

同样,对于分割,numpy也提供了更简单的方式vsplit和hsplit:

upper,lower=np.vsplit(A,[2])
upper
#out:array([[0, 1, 2, 3],
       [4, 5, 6, 7]])

数据分割对机器学习数据处理非常重要,比如一般数据格式是特征和分类label,特征要参与计算,需要把特征和label分开。

data=np.arange(16).reshape((4,4))
x,y=np.hsplit(data,[-1])#x是4×3矩阵
y
#out:array([[ 3],
       [ 7],
       [11],
       [15]])
y[:,0]#把提取到的label变成向量
out:array([ 3,  7, 11, 15])

实际处理矩阵数据时要随机应变。

上一篇下一篇

猜你喜欢

热点阅读