6.17学习:
np.array() Numpy中核心的就是array,numpy先天就把数组看作多维矩阵,进而进行矩阵的操作。
import numpynumpy.__version__
另外,因为要很经常的使用numpy,所以常常使用以下代码采用np来代替numpy。
python中list也可以表达数组,但是List没有对元素做类型的限制,一个List里可以有很多种数据类型,虽然灵活,但这导致List效率低下。
L = [i for i in range (10 )] L
输出:[0, 1, 2, 3, 4, 5, 6, 7, 8, 9]。
输出:[0, 1, 2, 3, 4, 100, 6, 7, 8, 9]。
L[5 ] = "Machine Learning" L
输出:[0, 1, 2, 3, 4, ‘Machine Learning’, 6, 7, 8, 9]。
当然,python中也有限定了只能存储一种数据类型的数组,来自array包的.array
方法。
import arrayarr = array.array('i' ,[i for i in range (10 )]) arr
输出:array(‘i’, [0, 1, 2, 3, 4, 5, 6, 7, 8, 9])。
Array中对元素的操作和List类似。
输出:5、array(‘i’, [0, 1, 2, 3, 4, 100, 6, 7, 8, 9])。
arr[5 ] = 'Machine Learning'
输出:TypeError: an integer is required (got type str),因为array中限定只能存储一种类型,这样虽然不灵活但效率高。
Array只是把存储在其中的数据当成一个数组来看,或者当成二维数组,而不是向量或矩阵,相对应的也就没有配备矩阵相关的运算,不适合机器学习。
所以我们使用numpy中的array来表示矩阵。
nparr = np.array([i for i in range (10 )])
输出:array([0, 1, 2, 3, 4, 5, 6, 7, 8, 9])。
nparr[5 ] nparr[5 ] = 100 nparr 输出:5 、array([ 0 , 1 , 2 , 3 , 4 , 100 , 6 , 7 , 8 , 9 ])。
nparr[5 ] = 'Machine Learning' nparr
输出:ValueError: invalid literal for int() with base 10: ‘Machine Learning’。由此可见,和List和array中的操作方法基本类似,但是numpy也封装了一些特殊的对array操作的方法。
没有报错,这是因为numpy在这里给5.20做了一次隐式类型转换。
nparr2 = np.array([1 ,2 ,3.0 ]) nparr2.dtype
Numpy有隐形类型转换机制,输出:dtype(‘float64’)。
np.zeros()、np.ones()、np.full() Numpy预置了很多创建数组的方法。
输出:array([0., 0., 0., 0., 0., 0., 0., 0., 0., 0.])。
输出:dtype(‘float64’)。
输出:array([[0., 0., 0., 0., 0.], [0., 0., 0., 0., 0.], [0., 0., 0., 0., 0.]])
输出:array([1., 1., 1., 1., 1., 1., 1., 1., 1., 1.])。
输出:array([[1., 1., 1., 1., 1.], [1., 1., 1., 1., 1.], [1., 1., 1., 1., 1.]])。
输出:array([[666, 666, 666, 666, 666], [666, 666, 666, 666, 666], [666, 666, 666, 666, 666]])。
np.full(fill_value=666.0 ,shape=(3 ,5 ))
np.arange() [i for i in range (0 ,20 ,2 )]
输出:[0, 2, 4, 6, 8, 10, 12, 14, 16, 18]。
输出:array([ 0, 2, 4, 6, 8, 10, 12, 14, 16, 18])。
输出:array([0, 1, 2, 3, 4, 5, 6, 7, 8, 9])。
np.linspace()
输出:array([ 0. , 2.22222222, 4.44444444, 6.66666667, 8.88888889, 11.11111111, 13.33333333, 15.55555556, 17.77777778, 20. ])。
输出:array([ 0., 2., 4., 6., 8., 10., 12., 14., 16., 18., 20.])。
np.random()
np.random.randint(0 ,10 ,10 )
输出:array([5, 9, 5, 6, 5, 4, 0, 8, 0, 8])。
np.random.randint(4 ,8 ,size=10 )
输出:array([6, 4, 7, 5, 7, 5, 6, 4, 5, 4])。
np.random.randint(4 ,8 ,size=(3 ,5 ))
输出:array([[4, 4, 6, 4, 6], [4, 7, 5, 6, 7], [6, 6, 7, 7, 6]])
计算机中的随机数都是伪随机,可以指定随机数种子,来让每一次生成的随机数都一样,方便我们调试。
np.random.seed(666 ) np.random.randint(4 ,8 ,size=(3 ,5 ))
np.random.randint(4 ,8 ,size=(3 ,5 ))
可见,前两次生成的随机数是一样的。
输出:array([[0.46284169, 0.23340091, 0.76706421, 0.81995656, 0.39747625], [0.31644109, 0.15551206, 0.73460987, 0.73159555, 0.8578588 ], [0.76741234, 0.95323137, 0.29097383, 0.84778197, 0.3497619 ]])
这时生成的随机数是在0-1之间随机分布的随机数,如果想生成符合正态分布的随机数,采用numpy.random.normal()
方法。
np.random.normal(0 ,1 ,(3 ,5 ))
输出:array([[-0.21326813, 0.44076692, 0.69339587, 0.03820097, -0.18592982], [-0.35371521, -1.95332994, -0.34376486, -1.47693162, -0.70022971], [ 0.77605168, 1.18063598, 0.06102404, 1.07856138, -0.79783572]])
np.array()的基本操作 前置代码。
import numpy as npx = np.arange(10 ) x
输出:array([0, 1, 2, 3, 4, 5, 6, 7, 8, 9])。
X = np.arange(15 ).reshape(3 ,5 ) X
输出:。array([[ 0, 1, 2, 3, 4], [ 5, 6, 7, 8, 9], [10, 11, 12, 13, 14]])
基本属性
np.array的数据访问
输出:array([0, 1, 2, 3, 4])。
输出:array([5, 6, 7, 8, 9])。
输出:array([0, 2, 4, 6, 8])。
输出:array([9, 8, 7, 6, 5, 4, 3, 2, 1, 0])。
输出:array([[0, 1, 2], [5, 6, 7]])
输出:array([[0, 1, 2, 3, 4], [5, 6, 7, 8, 9]])
输出:array([[0, 2, 4], [5, 7, 9]])
输出:array([[14, 13, 12, 11, 10], [ 9, 8, 7, 6, 5], [ 4, 3, 2, 1, 0]])
输出:array([0, 1, 2, 3, 4])。
输出:array([[0, 1, 2], [5, 6, 7]])
输出:array([[100, 1, 2], [ 5, 6, 7]])
输出:array([[100, 1, 2, 3, 4], [ 5, 6, 7, 8, 9], [ 10, 11, 12, 13, 14]])
在python中,对原矩阵切片的话是创建了一个新的矩阵,不会影响。但在numpy中,会影响被切片的矩阵。
输出:X和subX的第一位都别修改了。
如果想不相连,可以调用numpy中的copy()方法。
subX = X[:2 ,:3 ].copy() subX
输出:array([[0, 1, 2], [5, 6, 7]])
输出:array([[100, 1, 2], [ 5, 6, 7]])
输出:array([[ 0, 1, 2, 3, 4], [ 5, 6, 7, 8, 9], [10, 11, 12, 13, 14]])
np.reshape()
输出:array([[0, 1, 2, 3, 4], [5, 6, 7, 8, 9]])
输出:array([0, 1, 2, 3, 4, 5, 6, 7, 8, 9])。
输出:array([[0, 1, 2, 3, 4], [5, 6, 7, 8, 9]])。
此时x是一维向量,注意向量永远是一列,和二维矩阵的维度 是不同的(尽管1*10的二维矩阵看起来和10个元素的向量一样),可以用reshape方法把向量变成二维矩阵。
输出:array([[0, 1, 2, 3, 4, 5, 6, 7, 8, 9]])。
reshape还可以很智能的调配每一行的元素个数。
输出:array([[0], [1], [2], [3], [4], [5], [6], [7], [8], [9]])
输出:array([[0, 1], [2, 3], [4, 5], [6, 7], [8, 9]])
合并操作 x = np.array([1 ,2 ,3 ]) y = np.array([3 ,2 ,1 ])
输出: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 ],[4 ,5 ,6 ]]) np.concatenate([A,A])
输出:array([[1, 2, 3], [4, 5, 6], [1, 2, 3], [4, 5, 6]])。
np.concatenate([A,A],axis=1 )
输出:array([[1, 2, 3, 1, 2, 3], [4, 5, 6, 4, 5, 6]])。
输出:ValueError: all the input arrays must have same number of dimensions, but the array at index 0 has 2 dimension(s) and the array at index 1 has 1 dimension(s)。
np.concatenate([A,z.reshape(1 ,-1 )])
输出:array([[ 1, 2, 3], [ 4, 5, 6], [666, 666, 666]])。
输出:array([[1, 2, 3], [4, 5, 6]])。
A2 = np.concatenate([A,z.reshape(1 ,-1 )])
输出:array([[ 1, 2, 3], [ 4, 5, 6], [666, 666, 666]])。
输出:array([[ 1, 2, 3, 100, 100], [ 4, 5, 6, 100, 100]])。
输出:ValueError。
分割操作
x1, x2, x3 = np.split(x,[3 ,7 ])
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]])。
输出:array([[0, 1, 2, 3], [4, 5, 6, 7]])。
输出:array([[ 8, 9, 10, 11], [12, 13, 14, 15]])。
A1, A2 = np.split(A,[2 ],axis = 1 )
upper, lower = np.vsplit(A,[2 ])
输出:array([[0, 1, 2, 3], [4, 5, 6, 7]])。
left, right = np.hsplit(A,[2 ])
输出:array([[ 0, 1], [ 4, 5], [ 8, 9], [12, 13]])
数据的分割有什么意义呢?可以吧特征和label分开。
data = np.arange(16 ).reshape((4 ,4 )) x, y = np.hsplit(data,[-1 ])
输出:array([[ 0, 1, 2], [ 4, 5, 6], [ 8, 9, 10], [12, 13, 14]])。
输出:array([[ 3], [ 7], [11], [15]])。
有时我们希望抽出的label是列向量而不是二维数组,这个时候用切片的办法。
输出:array([ 3, 7, 11, 15])。