python numpy基础
numpy是一个python库, 这个库能够实现高效的数值计算,它的底层他使用c实现的, 在 python 常用如下方法导入 numpy 模块:
import numpy as np
import matplotlib.pyplot as plt
ndarray
ndarray 是numpy的重要组成部分, 是一种多维数据对象
ndarray 创建
ndarray 的创建有如下方法:
arr1 = np.array([1, 2, 3]) #可以使用列表、元祖、数组或者其他序列类型来创建 ndarray 对象
arr2 = np.asarray([1, 2, 3]) #输入转成array, 如果输入本身是ndarray对象, 怎不进行复制
arr3 = np.asarray(arr1)
print (id(arr1), id(arr2), id(arr3)) #发现 arr3 和 arr1 具有相同的 id
arr4 = np.arange(5) # 生成 5 个元素的 ndarray对象
arr5 = np.ones(shape = (2, 3)) #生成 2 * 3 的全1的数组
arr6 = np.ones_like(arr1) #生成和 arr1 形状相似的 全1数组
arr7 = np.zeros(shape = (2, 3))
arr8 = np.zeros_like(arr1)
arr9 = np.empty(shape = (2, 3)) #创建新数组,不赋值
arr10 = np.empty_like(arr1)
arr11 = np.eye(5)
arr12 = np.identity(5) #同 ery 方法,创建对角线元素是 1 的数组
arr13 = arr1.astype(np.float64) #arr1的数据类型,转换成float64
ndarray 数据类型
每个array对象,都有一个 dtype 的属性,表示这个对象的数据类型, 我们在创建ndarray数组的时候,如果不指定 dtype,会做默认转化
arr12.dtype??
元素级别运算
arr1 = np.arange(10).reshape(2, 5)
print (arr1)
print (arr1 + arr1)
print (arr1 * 2) #如下面输出,上面计算都是元素级别的
## 索引和切片 ##
#索引
arr = np.arange(10)
print (arr[3])
print (arr[3:5])
arr[3:5] = 13
print (arr) # 索引获取的是 arr 的 视图, arr.copy() 获取复制
# 二维数组
arr2d = np.arange(20).reshape(4, 5)
print (arr2d)
print (arr2d[2])
print (arr2d[2, 3])
#切片
print (arr[1:6])
print (arr2d[2:])
print (arr2d[2:, :3])
print (arr2d[:, :1]) #只有冒号表示选取整个轴
布尔索引
names = np.array(['bob', 'joe', 'will', 'bob', 'will', 'joe','joe'])
data = np.random.randn(7, 4)
print (names)
print (data) #data 每一行对应 names 每个元素的数据
print (data[names == 'bob']) # bob 的数据
print (data[~(names == 'bob')]) # 非bob数据
print (data[(names == 'bo') | (names == 'joe')]) # bob or joe 的数据
print (data[names == 'bob', :2])
data[data < 0] = 0 #负数置0
print (data)
花式索引
#花式索引 总是复制元素
arr = np.empty((8, 4))
for i in range(8):
arr[i] = i
print (arr)
print (arr[[3, 2, 1, 0]]) #特定顺序选取行元素
print (arr[[3, 2, 1, 0], [0, 1, 2 , 3]]) #选取的是 (3, 0), (2, 1), (1, 2), (0, 3) 元素
print (arr[[3, 2]][:, 1:3]) #选取矩阵子集
print (arr[np.ix_([3, 2], [1, 3])]) #选取矩阵子集
转置
#二维数组
arr2d = np.arange(10).reshape(2, 5)
print (arr2d)
print (arr2d.T) #转置
#多维数组 transpose
arrd3d = np.arange(24).reshape(2, 3, 4)
print (arr3d)
print (arr3d.transpose(1, 0, 2)) #最终得出来 (3, 2, 4) 数组,如果在源数组中的坐标是 (a, b, c), 那么新数组中的做标 (b, a, c)
print (arr3d.swapaxes(0, 1)) #和上面的结果相同
通用函数
一些常用数学函数, 如 np.max(), np.min , 都是元素级别的, 能够快速做数学运算
数据处理
主要是通过数据处理数据,这样就避免了写循环, 通常速度快 1 - 2 个数量级
# meshgrid
x = np.array([1, 2])
y = np.array([3, 4, 5])
(xs, ys) = np.meshgrid(x, y) #生成 x * y 的矩阵
print (xs)
print (ys)
points = np.arange(-5, 5, 0.01)
(xs, ys) = np.meshgrid(points, points)
z = np.square(xs**2 + ys**2)
plt.imshow(z, cmap = plt.cm.brg)
plt.title("Image plot of $\sqrt{x^2 + y^2}$ for a grid of values")
plt.show()
# np.where 条件逻辑表述为数组运算
xarr = np.array([1.1, 1.2, 1.3, 1.4, 1.5])
yarr = np.array([2.1, 2.2, 2.3, 2.4, 2.5])
cond = np.array([True, False, True, True, False])
result = np.where(cond, xarr, yarr)
print (result)
arr = np.random.randn(4, 4)
print (arr)
result = np.where(arr > 0, 2, -2)
print (result)
#常用的统计函数 mean / sum / std
arr = np.random.randn(5, 4)
print (arr)
print (arr.max()) #针对所有元素
print (arr.max(axis = 0)) #0轴上的统计信息, 这里相当于列
print (arr.max(axis = 1)) #1轴上的统计信息, 这里相当于行
#cumsum / cumprod 累积
arr = np.array([[0, 1, 2, ], [3, 5, 4], [6, 7, 8]])
print (arr)
print (arr.cumsum(0))
print (arr.cumprod(1))
#argmin / argmax 最大、最小索引
print (arr.argmax())
print (arr.argmax(0))
print (arr.argmax(1))
#排序 sort
arr.sort(0)
print (arr)
arr.sort(1)
print (arr)
## 集合操作函数 ##
np.unique(names) #
np.intersect1d(names, names) #计算公共元素
np.union1d(names, names) #并集
np.in1d(names, ['a', 'b', 'c']) #判断元素包含关系, 返回布尔型数组
np.setdiff1d(names, names) #集合差
np.setxor1d(names, names) #集合对称差
保存和读取文件
#保存
arr = np.arange(10)
np.save("some_array", arr) #未压缩
print (np.load("some_array.npy"))
np.savez('array_archive.npz', a = arr, b = arr) #压缩
arch = np.load('array_archive.npz')
print (arch['a'])
print (arch['b'])
#读取文本文件
#np.loadtxt() , 用 delimiter 指定分割符
随机数生成
#np.random 的部分函数如下
# seed --> 随机数种子
# permutation --> 返回一个序列的随机排列或者随机排列范围
# shuffle --> 就地随机排列
# rand --> 均匀分布
# randint --> 随机生成整数
# randn --> 正态分布
# binomial --> 二项分布样本值
# normal --> 正态分布
# beta --> beta分布
# chisquare --> 卡方分布
# gamma --> gamma 分布
# uniform --> [0, 1) 均匀分布
# 单个随机漫步
nsteps = 1000
draws = np.random.randint(0, 2, size = nsteps)
steps = np.where(draws > 0, 1, -1)
walks = steps.cumsum()
print (walks.min())
print (walks.max())
# 多个随机漫步
nwalks = 5000
nsteps = 1000
draws = np.random.randint(0, 2, size = (nwalks, nsteps))
steps = np.where(draws > 0, 1, -1)
walks = steps.cumsum(1)
#30 or -30 最小穿越时间
hits30 = (np.abs(walks) >=30).any(1) #生成一个bool数组, 行中含有true的表示 用户到达过 30 or -30
print (hits30.sum())
cross_times = (np.abs(walks[hits30]) >= 30).argmax(1)
print (cross_times.mean())