python量化交易笔记---10.numpy库使用
numpy是python中一个重要的科学计算库,是当前机器学习和深度学习的基础库之一。在numpy中最重要的就是多维数组,我们在这里重点向大家介绍一下多维数组的用法。
创建多维数组
range函数直接创建
采用range函数,创建下标由零开始的一维数组(其后可以通过reshape变为多维数组),数组元素值为由零开始的整数:
import numpy as np
# 定义数组并显示其内容、形状、类型
arr1 = np.array(range(6))
print('数组:{0},形状:{1},类型:{2}'.format(arr1, arr1.shape, type(arr1)))
# 改变形状1(原数组不变)
arr2 = arr1.reshape((2, 3))
print('arr2:{0}, shape:{1}'.format(arr2, arr2.shape))
# 改变原来的形状
arr1.shape = 2, 3
print('数组arr1:{0},形状:{1},类型:{2}'.format(arr1, arr1.shape, type(arr1)))
# 共享存储示例
arr1[1, 2] = 99
print('arr1:{0}; \narr2:{1}'.format(arr1, arr2))
第3~5行:我们首先定义的数组,其形状为(6,),类型为np.ndarray;
第6~8行:我们定义arr2,将上面的数组重新解读为的二维数组,注意这里仅是改变了解读方式,而底层数组存储没有变化,arr1还是一维数组;
第9~11行:我们直接改变arr1的形状,也变为数组
第12~14行:arr1和arr2虽然是两个数组变量,但是其数组数据是共享的,我们改变arr1中的内容,arr2相应位置元素的值也会跟着改变。
运行上面的程序,结果如下所示:
list生成数组
我们可以直接通过python语言中的list对象,直接生成numpy的多维数组:
import numpy as np
list1 = [[1, 3, 5, 7, 9], [2, 4, 6, 8, 10]]
arr1 = np.array(list1)
print('数组:{0}, 形状:{1}, 类型:{2}'.format(arr1, arr1.shape, type(arr1)))
arange生成数组
利用arange函数,可以规定数组的起始值、终止值(不包含)和步长,可以定义更加灵活的数组,如下所示(codes/c10c003.py):
import numpy as np
# 生成步长为0.2的递增数组,包含1不包含3
arr1 = np.arange(1, 3, 0.2)
print('arr1:{0}, shape:{1}, type:{2}'.format(arr1, arr1.shape, type(arr1)))
# 生成步长为-0.2的递减数组,包含3.1不包含1.1
arr2 = np.arange(3.1, 1.1, -0.2)
print('arr1:{0}, shape:{1}, type:{2}'.format(arr2, arr2.shape, type(arr2)))
运行结果为(images/f002.png):
利用linspace函数生成数组
利用np.arange生成多维数组有一个不太方便的地方,就是不能包括终止值,如果确实需要包括终止值,则可以使用linspace函数,如下所示(codes/c10c004.py):
import numpy as np
# 参数:起始点、终止点、中间所取点数,包括起点和终点
arr1 = np.linspace(1, 5, 10)
print('arr1:{0}, shape:{1}, type:{2}'.format(arr1, arr1.shape, type(arr1)))
运行结果(images/f003.png)为:
创建空数组
我们可以创建特定形状的数组,数组元素值为0或者1,如下所示(codes/c10c005.py):
import numpy as np
arr1 = np.zeros((2, 3), dtype=np.int)
print('arr1:{0}, shape:{1}, type:{2}'.format(arr1, arr1.shape, type(arr1)))
arr2 = np.ones((2, 3), dtype=np.float32)
print('arr1:{0}, shape:{1}, type:{2}'.format(arr2, arr2.shape, type(arr2)))
我们在创建数组时,还可以通过dtype来指定数组的类型。运行结果(images/f004.png)为:
利用正态分布随机数创建数组
在机器学习和深度学习项目中,层间的连接权值矩阵通常需要用很小的随机数来初始化,通常用正态分布的随机来进行初始化,如下所示(codes/c10c006.py):
import numpy as np
mu = 0.0
sigma = 0.1
w = np.random.normal(mu, sigma, 10)
print('w.shape:{0}, w.type:{1}\nw:{2}'.format(w.shape, type(w), w))
# tf.random_normal(shape=[2, 3], mean=mu, stddev=sigma).astype(tf.float32)
在上面的代码中,我们给出了在tensorflow中对应的方法,运行结果(images/f005.png)为:
选取数组元素
我们可以非常方便地从numpy数组中取出子数组,首先python数组元素选取与其他语言不太相同,对于多维数组来说格式为:,其中既可以是一个数字,代表对应维度下标;也可以表示该维度一个范围:表示第i维从下标开始(包含),到下标(不包含)为止的元素;我们还可以规定每隔多少个元素取一个:,表示每隔k个元素取一个。另外,-1代表最后一个元素,-2代表倒数第2个元素。
数组运算
numpy中的数组可以表示线性代数中的向量、矩阵和张量,但是线性代数中向量为列向量,可以用一维数组表示。向量有对应元素相乘和点积,矩阵同样有对应元素相乘和矩阵相乘,对应的程序如下所示:
import numpy as np
v1 = np.array([1, 2, 3], dtype=np.int)
v2 = np.array([4, 5, 6], dtype=np.int)
v3 = np.multiply(v1, v2)
v2_ = v2.reshape((3, 1))
print('v3:{0}, \nshape:{1}, type:{2}'.format(v3, v3.shape, type(v3)))
v4 = np.matmul(v1, v2)
print('v4:{0}, \nshape:{1}, type:{2}'.format(v4, v4.shape, type(v4)))
m1 = np.ones((2, 3), dtype=np.float32)
m1 *= 2
m2 = np.array([[1, 2, 3],[4, 5, 6]], dtype=np.float32)
m2_ = m2.reshape((3, 2))
m2_T = np.transpose(m2)
m3 = np.multiply(m1, m2)
print('m3:{0}, \nshape:{1}, type:{2}'.format(m3, m3.shape, type(m3)))
m4 = np.matmul(m1, m2_T)
print('m4:{0}, \nshape:{1}, type:{2}'.format(m4, m4.shape, type(m4)))
m5 = np.matmul(m1, m2_)
print('m5:{0}, \nshape:{1}, type:{2}'.format(m5, m5.shape, type(m5)))
运行结果如下所示:
除了以上基本内容以外,numpy数组还提供很多功能,例如求数组的和、平方和、求出最大值元素的下标、均值、方差、中位数,如下所示:
import numpy as np
arr1 = np.array([0.5, 1.43, -1.36, -0.16, 0.20, -0.59, 1.16], dtype=np.float32)
arr2 = arr1 ** 2
print(arr2)
print('max:{0:#0.2f}; min:{1:#0.2f}'.format(np.max(arr1), np.min(arr1)))
print('sum={0:#0.2f}; squred={1:#0.2f}'.format(np.sum(arr1), np.sum(arr2)))
print('idx={0:#0}'.format(np.argmax(arr1)))
print('mean={0:#0.2f}'.format(np.mean(arr1)))
print('stddev={0:#0.2f}; var={1:#0.2f}'.format(np.std(arr1), np.var(arr1)))
运行结果如下所示:
参考资料: