1 2 3 |
import numpy as np import matplotlib.pyplot as plt |
ndarray的属性
1 2 3 4 5 |
# 创建不同形状的数组 a = np.array([[1,2,3],[4,5,6]]) b = np.array([1,2,3,4]) c = np.array([[[1,2,3],[4,5,6]],[[1,2,3],[4,5,6]]]) |
1 2 |
a |
1 2 3 |
array([[1, 2, 3], [4, 5, 6]]) |
1 2 3 |
# shape属性: 数组维度, 返回元组 c.shape # 一维数组 元素个数;二维数组 行数 列数;三维数组形状表示 层数 行数 列数 |
1 2 |
(2, 2, 3) |
1 2 3 |
# 数组维数 c.ndim |
1 2 |
3 |
1 2 3 |
# 元素个数 c.size |
1 2 |
12 |
1 2 3 |
# 数组中元素字节数 a.itemsize |
1 2 |
4 |
1 2 3 |
# 数组中元素类型 a.dtype |
1 2 |
dtype('int32') |
基本操作
全0, 1数组的生成
1 2 3 4 5 6 7 8 9 10 |
# 生成全0数组 np.zeros((6, 6, 6)) # 生成全1数组 np.ones((6, 6, 6)) a = np.array([[1, 2, 3], [4, 5, 6]]) # 生成和a形状一样的全0 全1 数组 np.zeros_like(a) np.ones_like(a) |
1 2 3 |
array([[1, 1, 1], [1, 1, 1]]) |
从现有数组生成
1 2 3 4 5 6 7 8 9 10 11 12 13 |
# 以复制的形式生成新数组, 从a生成b b = np.array(a) # 以引用的形式生成新数组, 从a生成c, 共用同一块内存 c = np.asarray(a) a[0] = 10 a b c |
1 2 3 |
array([[10, 10, 10], [ 4, 5, 6]]) |
生成固定范围数组
1 2 3 |
# np.linspace(start, stop, num数量, endpoint) 从指定范围内取指定数量的元素 np.linspace(1, 10, 10) |
1 2 |
array([ 1., 2., 3., 4., 5., 6., 7., 8., 9., 10.]) |
1 2 3 |
# np.arange(start, start, step步长) 左闭右开 从指定范围内按指定步长取值 np.arange(1, 11, 2) |
1 2 |
array([1, 3, 5, 7, 9]) |
1 2 3 |
# np.logspace(start, stop, num数量, base=比例) 生成等比数列, base默认是10 np.logspace(1, 10, 10, base=2) |
1 2 3 |
array([ 2., 4., 8., 16., 32., 64., 128., 256., 512., 1024.]) |
生成随机数组
1 2 3 4 5 6 7 8 9 |
# 均匀抽样生成随机数组 np.random模块的三个方法 np.random.rand(2, 3, 4) # shape元组不带括号 0-1 标准正态分布 # 指定范围内生成随机数组(浮点数) np.random.uniform(1, 10, (2, 3)) # 指定范围内生成随机数组(整数) np.random.randint(1, 10, (2, 3)) |
1 2 3 |
array([[6, 4, 6], [2, 2, 5]]) |
1 2 3 4 5 6 7 8 9 10 |
# 正态分布抽样生成随机数组的三个函数 # 标准正态分布抽样 np.random.randn(2, 3) # randn即rand normal # np.random.normal(平均值, 标准差, size=(2, 3)) np.random.normal(loc=1, scale=1, size=(2, 3)) # 标准正态分布抽样 np.random.standard_normal((2, 3)) # shape带括号 |
1 2 3 |
array([[ 0.26555982, -1.49885147, -0.55455344], [-0.15375737, -0.01664176, 0.07966012]]) |
绘制直方图
1 2 3 4 5 6 7 8 9 10 11 12 |
# 绘制均匀分布抽样生成的数据的直方图 x = np.random.uniform(-10, 10, 1000000) # 创建画布 plt.figure(figsize=(20, 8)) # 绘制图像, bins分成1000个区间 plt.hist(x, bins=1000) # 显示图像 plt.show() |
1 2 3 4 5 6 7 8 9 10 11 12 |
# 绘制正态分布抽样生成的数据的直方图 x_n = np.random.standard_normal((1000000,)) # 创建画布 plt.figure(figsize=(20, 8)) # 绘制图像, bins分成1000个区间 plt.hist(x_n, bins=1000) # 显示图像 plt.show() |
数组索引和切片
案例:随机生成8只股票1周的交易日涨幅数据
1 2 3 4 |
# 随机生成一个8行10列的数组 stock_chage = np.random.standard_normal((8, 5)) stock_chage |
1 2 3 4 5 6 7 8 9 |
array([[ 0.81239017, -0.42808824, 0.25077363, 0.79254236, -1.16268171], [ 2.09632515, 1.52687036, -1.25748286, 0.07041701, -2.40635915], [ 1.61338417, -0.1106411 , 0.81586067, -0.23399652, 0.97836168], [ 0.21667804, -0.23204809, -0.63936204, 1.89696006, -0.63397887], [ 0.93199368, 0.47896579, -0.71323795, -0.15157494, 0.50150145], [ 0.49511437, -0.11304412, -0.70284119, 0.68157345, -0.4618224 ], [ 2.28817882, 1.39489871, 0.04182514, 0.23709402, -0.30483556], [-0.48157944, 0.56814202, -0.26051617, 0.18179547, 0.4111354 ]]) |
1 2 3 |
# 起始:结束:步长 stock_chage[0,:] |
1 2 |
array([ 0.81239017, -0.42808824, 0.25077363, 0.79254236, -1.16268171]) |
1 2 |
stock_chage[:2,:] |
1 2 3 |
array([[ 0.81239017, -0.42808824, 0.25077363, 0.79254236, -1.16268171], [ 2.09632515, 1.52687036, -1.25748286, 0.07041701, -2.40635915]]) |
1 2 3 |
# 切片的方法, 每个维度用冒号索引进行切片, 有多少个维度, 就传多少个冒号索引 stock_chage[:4:2,:] |
1 2 3 |
array([[ 0.81239017, -0.42808824, 0.25077363, 0.79254236, -1.16268171], [ 1.61338417, -0.1106411 , 0.81586067, -0.23399652, 0.97836168]]) |
1 2 3 4 |
# 赋值修改 stock_chage[0,0] = 10 stock_chage |
1 2 3 4 5 6 7 8 9 |
array([[10. , -0.42808824, 0.25077363, 0.79254236, -1.16268171], [ 2.09632515, 1.52687036, -1.25748286, 0.07041701, -2.40635915], [ 1.61338417, -0.1106411 , 0.81586067, -0.23399652, 0.97836168], [ 0.21667804, -0.23204809, -0.63936204, 1.89696006, -0.63397887], [ 0.93199368, 0.47896579, -0.71323795, -0.15157494, 0.50150145], [ 0.49511437, -0.11304412, -0.70284119, 0.68157345, -0.4618224 ], [ 2.28817882, 1.39489871, 0.04182514, 0.23709402, -0.30483556], [-0.48157944, 0.56814202, -0.26051617, 0.18179547, 0.4111354 ]]) |
1 2 3 4 5 |
# 形状修改的两种方法 temp = np.linspace(1, 12, 12) # reshape不修改原数组,返回新数组 res = temp.reshape((3, 4)) # 内存中1到12连续储存,reshape resize不改变储存结构 |
1 2 3 4 |
# resize修改原数组, 没有返回值 temp.resize((3, 4)) temp |
1 2 3 4 |
array([[ 1., 2., 3., 4.], [ 5., 6., 7., 8.], [ 9., 10., 11., 12.]]) |
1 2 3 |
# 转置 行列互换 返回转置数组(修改原数组存储顺序),原数组不变 temp.T |
1 2 3 4 5 |
array([[ 1., 5., 9.], [ 2., 6., 10.], [ 3., 7., 11.], [ 4., 8., 12.]]) |
类型修改
1 2 3 4 |
# 修改类型的两种方法 # 不修改原数组,生成新数组返回 res = temp.astype(np.int64) |
1 2 |
temp.dtype |
1 2 |
dtype('float64') |
1 2 |
res.dtype |
1 2 |
dtype('int64') |
1 2 3 |
# 把ndarray对象序列化, 返回二进制序列, 不修改原数组,生成新数组返回 s = temp.tostring() |
1 2 3 |
# 二进制序列转回一维数组, 再reshape np.frombuffer(s, dtype=np.float64).reshape((3, 4)) |
1 2 3 4 |
array([[ 1., 2., 3., 4.], [ 5., 6., 7., 8.], [ 9., 10., 11., 12.]]) |
数组去重
1 2 |
temp = np.array([[1, 2, 3, 4],[3, 4, 5, 6]]) |
1 2 |
temp |
1 2 3 |
array([[1, 2, 3, 4], [3, 4, 5, 6]]) |
1 2 3 |
# unique()方法去重返回一维数组, # unique()方法去重返回一维数组 np.unique(temp) |
1 2 |
array([1, 2, 3, 4, 5, 6]) |
1 2 |
temp |
1 2 3 |
array([[1, 2, 3, 4], [3, 4, 5, 6]]) |
1 |
<br /> |
1 2 3 |
import numpy as np import matplotlib.pyplot as plt |
ndarray运算
逻辑运算
1 2 |
stock_change = np.random.standard_normal((8, 5)) |
1 2 3 |
# 逻辑判断, 对每个元素做相应的逻辑判断, 大于0.5标记为True stock_change > 0.5 |
1 2 3 4 5 6 7 8 9 |
array([[ True, True, False, True, False], [False, False, False, True, False], [False, True, False, False, False], [ True, False, False, True, False], [ True, False, False, True, True], [False, False, False, False, True], [False, True, False, True, False], [False, False, False, False, False]]) |
1 2 3 4 5 |
# bool索引 temp = stock_change > 0.5 # 取出temp中为True的元素的值, 返回一维数组 stock_change[temp] |
1 2 3 4 |
array([0.82701473, 0.52815447, 1.30280975, 0.99423388, 1.44920605, 1.82899722, 1.11178331, 0.85886997, 1.62521657, 1.92676266, 1.25921207, 0.59098754, 1.78298366]) |
1 2 3 |
# 判断数组stock_change[0:2, 0:5]是否全是True, np.all(bool数组) np.all(stock_change[0:2, 0:5] > 0) |
1 2 |
False |
1 2 3 4 |
# 判断前五行是否>0 # 判断数组中是否有True, np.any(bool数组) np.any(stock_change[:5, :] > 0) |
1 2 |
True |
1 2 3 4 |
# 判断数组中>0的置为1, 否则为0, np.where(bool数组, true替换为, false替换为) temp = stock_change[:4,:4] > 0 np.where(temp, 1, 0) |
1 2 3 4 5 |
array([[1, 1, 1, 1], [0, 0, 0, 1], [0, 1, 0, 1], [1, 1, 0, 1]]) |
1 2 3 4 |
# 判断数组>0.5或<-0.5>的换为1, 否则为0, np.logical_or np.logical_and temp = np.logical_or(stock_change[:4,:4] > 0.5, stock_change[:4,:4] < -0.5) np.where(temp, 1, 0) |
1 2 3 4 5 |
array([[1, 1, 0, 1], [1, 1, 1, 1], [1, 1, 1, 0], [1, 0, 1, 1]]) |
统计运算
1 2 3 4 5 6 7 8 9 |
# min 最小值 # max 最大值 # argmax最大值下标 # median 中位数 # mean 平均数 # std 标准差 # var 方差 temp = stock_change[:4,:4] |
1 2 3 |
# aixs=1按行计算 aixs=1按列计算 np.max(temp, axis=1) |
1 2 |
array([1.30280975, 0.99423388, 1.44920605, 1.82899722]) |
1 2 3 |
# 求每一行的中位数 np.median(temp, axis=1) |
1 2 |
array([ 0.6775846 , -1.12488726, -0.36269486, 0.7945195 ]) |
1 2 3 |
# 限制最大值的位置 np.argmax(temp, axis=1) |
1 2 |
array([3, 3, 1, 0], dtype=int64) |
数组之间的运算
1 2 |
arr_0 = np.array([[1, 2, 3, 2, 1, 4], [5, 6, 1, 2, 3, 1]]) |
1 2 3 |
# 数组与标量的运算 arr_0 + 1 |
1 2 3 |
array([[2, 3, 4, 3, 2, 5], [6, 7, 2, 3, 4, 2]]) |
1 2 |
arr_1 = np.linspace(1, 12 ,12).reshape((2, 6)) |
1 2 3 |
# 直接进行加减乘除: 同形状数组(同型数组)对应元素加减乘除 arr_0 + arr_1 |
1 2 3 |
array([[ 2., 4., 6., 6., 6., 10.], [12., 14., 10., 12., 14., 13.]]) |
1 2 3 4 |
# 广播机制 arr_2 = np.array([[4], [6]]) arr_0 + arr_2 # 先以复制的形式对arr_2进行拓展成(2, 6)形状, 再相加 |
1 2 3 |
array([[ 5, 6, 7, 6, 5, 8], [11, 12, 7, 8, 9, 7]]) |
1 2 3 |
arr_3 = np.array([1, 2, 3, 4, 5, 6]) arr_0 + arr_3 |
1 2 3 |
array([[ 2, 4, 6, 6, 6, 10], [ 6, 8, 4, 6, 8, 7]]) |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 |
# 矩阵乘法np.matmul np.dot score = np.array([[80, 86], [82, 80], [85, 78], [90, 90], [86, 82], [82, 90], [78, 80], [92, 94]]) # 形状(8, 2) # 构造右矩阵(权重矩阵) w = np.array([[0.3], [0.7]]) # 矩阵乘法 np.matmul(a, b) 严格执行矩阵乘法, 优先使用, 代码含义明确 np.matmul(score, w) # 矩阵乘法 np.dot 支持参数为标量 np.dot(score, 10) |
1 2 3 4 5 6 7 8 9 |
array([[800, 860], [820, 800], [850, 780], [900, 900], [860, 820], [820, 900], [780, 800], [920, 940]]) |
1 |
<br /> |
ndarray与原生list效率对比
1 2 3 4 |
a = [] for i in range(100000000): a.append(random.random()) |
1 2 |
%time sum(a) # list求和时间, 魔法方法%time ??? |
1 2 3 |
Wall time: 980 ms 49997458.77791844 |
1 2 |
b = np.array(a) # 创建ndarry对象 |
1 2 3 |
# numpy求和时间 %time np.sum(b) |
1 2 3 |
Wall time: 349 ms 49997458.77793469 |