numpy学习笔记四——文件操作、线性代数、伪随机数生成

使用数组进行文件输入和输出

NumPy可以在硬盘中将数据以文本或二进制文件的形式进行存入硬盘或由硬盘载入。

np.save和np.load是高效存取硬盘数据的两大工具函数。数组在默认情况下是以未压缩的格式进行存储的,后缀名是.npy:

In [122]: arr = np.arange(10)

In [123]: np.save('some_array',arr)

如果文件存放路径中没写.npy时,后缀名会被自动加上。硬盘上的数组可以使用np.load进行载入:

In [124]: np.load('some_array.npy')
Out[124]: array([0, 1, 2, 3, 4, 5, 6, 7, 8, 9])

你还可以使用np.savez并将数组作为参数传递给该函数,用于在未压缩文件中保存多个数组,并且在载入一个.npy文件的时候,你会获得一个字典型的对象,并通过该对象很方便地载入单个数组:

In [126]: np.savez('array',a=arr,b=arr)

In [127]: arch = np.load('array.npz')

In [128]: arch['a']
Out[128]: array([0, 1, 2, 3, 4, 5, 6, 7, 8, 9])

如果你的数据已经压缩好了,你可能会想要使用numpy.savez_compressed将数据存入已经压缩的文件:

np.savez_compressed('array_compressed',a=arr,b=arr)

线性代数

线性代数,比如矩阵乘法、分解、行列式等方阵数学,是所有数组类库的重要组成部分。和Matlab等其他语言相比,NumPy的线性代数中所不同的是*是矩阵的逐元素乘积,而不是矩阵的点乘积.

In [130]: a = np.arange(6).reshape(2,3)

In [131]: a.T
Out[131]:
array([[0, 3],
       [1, 4],
       [2, 5]])

In [132]: a.dot(a.T)
Out[132]:
array([[ 5, 14],
       [14, 50]])

a.dot(y)等价于np.dot(a, a.T):

In [133]: np.dot(a,a.T)
Out[133]:
array([[ 5, 14],
       [14, 50]])

特殊符号@也作为中缀操作符,用于点乘矩阵操作

In [134]: a@a.T
Out[134]:
array([[ 5, 14],
       [14, 50]])

numpy.linalg拥有一个矩阵分解的标准函数集,以及其他常用函数,例如求逆和行列式求解:

In [135]: from numpy.linalg import inv,qr

In [136]: X = np.random.randn(5,5)

In [137]: mat = X.T.dot(X)

In [138]: inv(mat)
Out[138]:
array([[ 9.3067492 ,  3.44854363,  4.17202619, 13.58984599,  0.90081391],
       [ 3.44854363,  1.44927182,  1.54939926,  4.93141315,  0.23863412],
       [ 4.17202619,  1.54939926,  2.08179238,  6.06650012,  0.38660456],
       [13.58984599,  4.93141315,  6.06650012, 20.87441372,  1.42189132],
       [ 0.90081391,  0.23863412,  0.38660456,  1.42189132,  0.44630741]])

In [139]: mat.dot(inv(mat))
Out[139]:
array([[ 1.00000000e+00,  3.32949197e-16,  1.64815059e-16,
        -7.53088361e-15,  6.30895206e-16],
       [-1.61352798e-15,  1.00000000e+00, -7.46202572e-16,
         6.55728240e-15, -4.78719380e-16],
       [-2.70937042e-15, -7.11231664e-16,  1.00000000e+00,
         6.00287861e-15, -2.41241770e-16],
       [-3.18403374e-15,  5.08117251e-16,  2.07727866e-16,
         1.00000000e+00, -2.38722434e-16],
       [ 5.71097933e-16,  3.94927081e-16,  4.20154194e-16,
         3.09053489e-15,  1.00000000e+00]])

In [140]: q,r = qr(mat)

In [141]: r
Out[141]:
array([[-7.00190539,  6.75040451,  3.40710232,  1.85422572,  1.92828278],
       [ 0.        , -4.65811698,  2.78909461,  0.41797978, -1.70677991],
       [ 0.        ,  0.        , -2.96084437,  0.93058062, -0.68695004],
       [ 0.        ,  0.        ,  0.        , -0.18905376,  2.68971634],
       [ 0.        ,  0.        ,  0.        ,  0.        ,  0.55565501]])

表达式X.T.dot(X)计算的是X和它的转置矩阵X.T的点乘积。

  • 常用numpy.linalg函数
函数描述
diag将一个方阵的对角(或非对角)元素作为一维数组返回,或者将一维数组转换成一个方阵,并且在非对角线上有零点
dot矩阵点乘
trace计算对角元素和
det计算矩阵的行列式
eig计算方阵的特征值和特征向量
inv计算方阵的逆方阵
pinv计算矩阵的Moore-Penrose伪逆
qr计算QR分解
svd计算奇异值分解(SVD)
solve求解x的线性系统Ax=b,其中A是方阵
lstsq计算Ax=b的最小二乘值

伪随机数生成

numpy.random模块填补了Python内建的random模块的不足,可以高效地生成多种概率分布下的完整样本值数组。例如,你可以使用normal来获得一个4×4的正态分布样本数组:

In [142]: samples = np.random.normal(size=(4,4))

In [143]: samples
Out[143]:
array([[-1.21035431,  1.44097644,  1.28213326,  1.86843877],
       [ 0.41575756, -1.18904899,  0.90445916, -0.29414209],
       [-1.65952097,  0.45124761, -0.80380502,  0.74126157],
       [-1.11698142,  0.37450006,  1.71495999,  0.8454006 ]])

然而Python内建的random模块一次只能生成一个值。你可以从下面的示例中看到,numpy.random在生成大型样本时比纯Python的方式快了一个数量级:

In [144]: from random import normalvariate

In [145]: N = 1000000

In [146]: %timeit samples = [normalvariate(0,1) for _ in range(N)]
1.03 s ± 1.26 ms per loop (mean ± std. dev. of 7 runs, 1 loop each)

In [147]: %timeit np.random.normal(size=N)
39.5 ms ± 27.1 µs per loop (mean ± std. dev. of 7 runs, 10 loops each)

我们可以称这些为伪随机数,因为它们是由具有确定性行为的算法根据随机数生成器中的随机数种子生成的。你可以通过np.random.seed更改NumPy的随机数种子:

In [148]: np.random.seed(1234)

numpy.random中的数据生成函数公用了一个全局的随机数种子。为了避免全局状态,你可以使用numpy.random.RandomState生成一个随机数生成器,使数据独立于其他的随机数状态

In [149]: rng = np.random.RandomState(1234)

In [150]: rng.randn(10)
Out[150]:
array([ 0.47143516, -1.19097569,  1.43270697, -0.3126519 , -0.72058873,
        0.88716294,  0.85958841, -0.6365235 ,  0.01569637, -2.24268495])
  • numpy.random中的部分函数列表
函数描述
seed向随机数生成器传递随机状态种子
permulatation返回一个序列的随机排序,或者返回一个乱序的整数范围序列
shuffle随机排列一个序列
rand从均匀分布中抽取样本
randint根据给定的由低到高的范围抽取随机整数
randn从均值0方差1的正态分布中抽取样本(MATLAB型接口)
binomial从二项分布中抽取样本
normal从正态(高斯)分布中抽取样本
beta从beta分布中抽取样本
chisquare从卡方分布中抽取样本
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

绿豆蛙给生活加点甜

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值