Numpy

Python学习笔记(4):Numpy基础之线性代数与随机数

2019-02-08  本文已影响1人  刘爱玛

目录

一、线性代数

经过之前的学习,可以看出numpy中的“*”代表的是数组元素相乘的积,而不是一个矩阵点积。numpy.dot()方法可用于计算矩阵点积。

import numpy as np
x = np.array([[1, 2, 3], [4, 5, 6]])
y = np.array([[6, 23], [-1, 7], [8, 9]])
x.dot(y) #相当于np.dot(x, y)
输出:array([[ 28,  64],
       [ 67, 181]])

其他线性代数用法可参照下表。


numpy.linalg函数

以逆矩阵和QR分解为例:

from numpy.linalg import inv, qr
from numpy.random import randn
x = randn(5, 5)
mat = x.T.dot(x)
np.dot(mat, inv(mat))
输出:array([[ 1.00000000e+00, -1.59370706e-15, -1.88828683e-14,
        -3.43052196e-14,  3.51013317e-14],
       [-1.53698947e-15,  1.00000000e+00, -1.21613733e-14,
         1.99811095e-14,  1.00622429e-15],
       [ 1.76446186e-14,  3.77298874e-15,  1.00000000e+00,
        -5.48563879e-14,  5.66208107e-14],
       [-7.31782239e-16,  2.55275470e-15, -9.30027896e-15,
         1.00000000e+00, -5.52945469e-14],
       [-2.84309851e-14,  8.77601666e-15, -6.92602905e-15,
         5.25997190e-14,  1.00000000e+00]])

q, r = qr(mat)
r
输出:array([[-4.27798694e+00,  3.73498633e-01,  8.19716104e-01,
        -5.68358463e+00, -4.81236933e+00],
       [ 0.00000000e+00, -4.13734392e+00, -4.05451619e+00,
         2.51959891e+00, -4.00946801e-01],
       [ 0.00000000e+00,  0.00000000e+00, -1.11719697e+00,
        -8.14783975e-01, -1.73043130e+00],
       [ 0.00000000e+00,  0.00000000e+00,  0.00000000e+00,
        -2.85796658e+00, -3.65860503e+00],
       [ 0.00000000e+00,  0.00000000e+00,  0.00000000e+00,
         0.00000000e+00,  4.34438722e-03]])

二、随机数生成

numpy中的随机数生成有多种函数,我们之前常用的randn就是其中之一。


numpy.random函数

示例:随机漫步

学到这里的盆友可以把这个示例作为一个小练习,先明确问题然后自己动手写一下试试。
问题:从0开始,步长-1和1出现的概率相等,请模拟1000步的漫步情况。
思路:首先应该选取一个合适的随机数生成函数来确定每一步是-1还是1,注意概率要相同。通过对函数表的分析,randint是一个合适的函数,randint(a, b)表示生成一个随机数n, a <= n < b。
接下来只需要按照随机数值选择步距就可以了。

实现代码:

from numpy import random
import matplotlib.pyplot as plt
#定义变量
steps = 1000 #步数1000
position = 0
walks = np.zeros(steps)
walk = 0
#开始漫步
for i in range(steps):
    walk = 1 if random.randint(0, 2) else -1
    position = position + walk
    walks[i] = position
plt.plot(range(100), walks[:100])
输出:

这是最容易想到的实现方法,接下来问题升级,能否不用for循环,而是用数据运算来解决这个问题。
我们看到for循环里是有一个if判断逻辑的,可以用np.where函数来完成这个任务。

#定义变量
steps = 1000 #步数1000
walks = np.zeros(steps)
walk = np.zeros(steps)
#生成随机数组
rand_number = np.random.randint(0, 2, size = steps)
#利用随机数组计算每一步的步距
walk = np.where(rand_number > 0, 1, -1)
#用cumsum()函数计算数组累积和
walks = walk.cumsum()
plt.plot(range(100), walks[:100])
输出:

问题继续升级,如果想同时计算多个随机漫步,需要如何来实现。walks变量现在是一个规模为1000的一维数组,如果想解决升级后的问题,只需要将walks变为N*1000的二维数组就可以了。

#定义变量
steps = 1000 #步数1000
walks_n = 5 #有5个随机漫步同时进行
walks = np.zeros(steps)
walk = np.zeros(steps)
#生成随机数组
rand_number = np.random.randint(0, 2, size = (walks_n, steps))
#利用随机数组计算每一步的步距
walk = np.where(rand_number > 0, 1, -1)
#用cumsum()函数计算数组累积和
walks = walk.cumsum(1)
walks
输出:array([[  1,   0,   1, ..., -20, -19, -20],
       [  1,   2,   3, ...,  18,  19,  20],
       [ -1,  -2,  -1, ..., -26, -25, -24],
       [  1,   2,   3, ...,  52,  51,  52],
       [  1,   2,   1, ...,  46,  45,  44]])

如果需要统计N次随机漫步中,最远到达过30的漫步,可以利用布尔型数组来完成。

hits30 = (np.abs(walks) >= 30)
hits30
输出:array([[False, False, False, ..., False, False, False],
       [False, False, False, ..., False, False, False],
       [False, False, False, ..., False, False, False],
       [False, False, False, ...,  True,  True,  True],
       [False, False, False, ...,  True,  True,  True]])

hits30.any(1)
输出:array([False, False,  True,  True,  True])

#作图验证
plt.plot(range(1000), walks[3])
输出:

可以看到确实超过了30.
好的,numpy这章终于学习完毕,哦也。

上一篇下一篇

猜你喜欢

热点阅读