本文主要介绍一下在机器学习上经常会用到的Numpy的一些知识。供刚入门的研究者参考。
-
Numpy的数据格式
import numpy as np num1 = np.array([1,2,3,4,5]) print(type(num1)) print(num1) print(num1.shape) 输出为: <class 'numpy.ndarray'> [1 2 3 4 5] (5,)
Numpy的数据类型为 numpy.ndarray格式,这是numpy里最核心的结构,所有的numpy数据都是ndarray格式;打印出的结果在这里可以将其看作是矩阵。Numpy数据的shape功能是很常用的功能。对于一维矩阵,只显示一维矩阵里有多少个元素。
-
创建矩阵
#创建一维矩阵
num1 = np.array([1,2,3,4,5])
#创建二位矩阵
num2 = np.array([[1,4,7],[2,5,8],[3,6,9]])
#打印矩阵
print('num1: %s' % (num1))
print('num2: %s%s' % ('\n',num2))
#打印矩阵的shape
print('shape of num1: %s' % str(num1.shape))
print('shape of num2: %s' % str(num2.shape))
打印结果为:
num1: [1 2 3 4 5]
num2:
[[1 4 7]
[2 5 8]
[3 6 9]]
shape of num1: (5,)
shape of num2: (3, 3)
创建矩阵的格式为 np.array()。需要的参数是传入一个list数组。而且只能传入与一个list数组,当创建一维数组时,就直接写入元素,当创建二维数组时,就在list数组里在写入list数组。多维数组依次类推。一维数组的shape显示的是元素的个数,多维数组显示的是行列的数目,行列相乘是数组内元素的个数。可以用num2.size查看数组内元素的个数。shape这个属性在神经网络里会经常用到
-
数据存取
num1 = np.array([[1,2,3,4],[5,6,7,8],[9,10,11,12]])
print(num1)
输出:
[[ 1 2 3 4]
[ 5 6 7 8]
[ 9 10 11 12]]
print(num1[1,2]) #取第二行第三列的元素
输出:
7
print(num1[:,3]) #取所有行的第四列元素
输出:
[ 4 8 12]
print(num1[0:2,:]) #取第一行,第二行上所有的列元素
输出:
[[1 2 3 4]
[5 6 7 8]]
对于数据的存取和Python里对list的数据存取的方式是一样的,同样是按照数组的索引来进行。只需指定元素所在的行和列坐标即可(行和列的下标计数都是从0开始的)。
-
数据计算
num1 = np.array([5,10,15,20])
print(num1 == 10)
输出为:
[False True False False]
num2 = np.array([[1,4,7],[2,5,8],[3,6,9]])
print(num2 == 6)
输出为:
[[False False False]
[False False False]
[False True False]]
#可以利用bool值作为数组的索引来进行取值
boo = num2 == 6
print(num2[boo])
输出为:
6
可以看出数组元素是可以进行计算的,返回的结果就是和本数组同样大小的bool数组。然后这个bool数组是可以作为索引进行数组的存取的。
-
数据的维度
num1 = np.array([[1,4,7],[2,5,8],[3,6,9]])
print(num1)
输出为:
[[1 4 7]
[2 5 8]
[3 6 9]]
print(num1.sum(axis = 1)) #按行进行数据的求和
输出为:
[12 15 18]
print(num1.sum(axis = 0)) #按列记性数据的求和
输出为:
[ 6 15 24]
调用数组的求和方法,可以指定进行求和的维度,axis = 1是代表的是按行元素进行求和, axis = 0 时按照列元素进行求和。
-
矩阵的变换
num1 = np.array([1,2,3,4,5,6,7,8,9,10,11,12])
num2 = num1.reshape((3,4))
print(num2)
输出为:
[[ 1 2 3 4]
[ 5 6 7 8]
[ 9 10 11 12]]
print(num2.shape)
输出为:
(3, 4)
调用数据的reshape函数可以改变数组的维度,这里传入的参数是个元组,分别为新数组的行和列。
-
Numpy.random
num1 = np.random.random((3,4))
print(num1)
输出为:
[[ 0.24352393 0.45895736 0.72571055 0.33239218]
[ 0.34497247 0.82351852 0.27969111 0.18088519]
[ 0.08224769 0.42819389 0.00319244 0.34156103]]
这个函数在神经网络里为权值初始化的时候经常会用到,这里只简单的展示了一下它的使用。具体的话会有很多变形。而其根源就是这个函数会产生[-1,1)的随机值。
-
矩阵的拼接
num1 = np.floor(10*np.random.random((2,2)))
print(num1)
输出为:
[[ 9. 6.]
[ 1. 0.]]
num2 = np.floor(10*np.random.random((2,2)))
print(num2)
输出为:
[[ 2. 2.]
[ 0. 0.]]
print(np.hstack((num1,num2))) #横着进行拼接
输出为:
[[ 9. 6. 2. 2.]
[ 1. 0. 0. 0.]]
print(np.vstack((num1,num2))) #竖着进行拼接
输出为:
[[ 9. 6.]
[ 1. 0.]
[ 2. 2.]
[ 0. 0.]]
这里的拼接可以将横着拼接理解为为样本增加特征(一行代表一个样本,一列代表一个特征)。将竖着拼理解增加样本。
-
矩阵的复制
num1 = np.arange(12)
num2 = num1
print(num2 is num1)
输出为:
True
num2.shape = 3,4
print(num1.shape)
输出为:
(3,4)
print(id(num1))
输出为:
2738983811152
print(id(num2))
输出为:
2738983811152
num3 = num1.view()
print(num3 is num1)
输出为:
False
num3.shape = 2,6
print(num1.shape)
输出为:
(3,4)
print(id(num1))
输出为:
2738983811152
print(id(num3))
输出为:
2738983811792
num3[1,2] = 222
print(num1)
输出为:
[[ 0 1 2 3]
[ 4 5 6 7]
[222 9 10 11]]
num4 = num1.copy()
num4[2,2] = 8888
print(num1)
输出为:
[[ 0 1 2 3]
[ 4 5 6 7]
[222 9 10 11]]
这里矩阵的复制分为三种类型,第一种是把数据和地址全部复制(用的是 “=”,这里对两者任何的一个改变都是一样的)。第二种是只把数据复制,但是两个变量的ID不同(用的是 .view())。但是此时两者是公用一个内存的,改变其中的数据会在另一个相映的位置对另一个数据进行改变。第三种就是只复制数据,id和指向的内存区域全部不相同。