关于python:NumPy之ndarray中的函数

44次阅读

共计 5418 个字符,预计需要花费 14 分钟才能阅读完成。

简介

在 NumPy 中,多维数组除了根本的算数运算之外,还内置了一些十分有用的函数,能够放慢咱们的科学计算的速度。

简略函数

咱们先看下比拟常见的运算函数,在应用之前,咱们先结构一个数组:

arr = np.arange(10)
array([0, 1, 2, 3, 4, 5, 6, 7, 8, 9])

计算数组中元素的开方:

np.sqrt(arr)
array([0.    , 1.    , 1.4142, 1.7321, 2.    , 2.2361, 2.4495, 2.6458,
       2.8284, 3.    ])

天然常数 e 为底的指数函数:

np.exp(arr)
array([   1.    ,    2.7183,    7.3891,   20.0855,   54.5982,  148.4132,
        403.4288, 1096.6332, 2980.958 , 8103.0839])

取两个数组的最大值,组成新的数组:

x = np.random.randn(8)
y = np.random.randn(8)
x,y
(array([-2.3594, -0.1995, -1.542 , -0.9707, -1.307 ,  0.2863,  0.378 ,
        -0.7539]),
 array([ 0.3313,  1.3497,  0.0699,  0.2467, -0.0119,  1.0048,  1.3272,
        -0.9193]))
np.maximum(x, y)
array([ 0.3313,  1.3497,  0.0699,  0.2467, -0.0119,  1.0048,  1.3272,
       -0.7539])

返 回浮点数数组的小数和整数局部:

arr = np.random.randn(7) * 5
array([-7.7455,  0.1109,  3.7918, -3.3026,  4.3129, -0.0502,  0.25])
remainder, whole_part = np.modf(arr)
(array([-0.7455,  0.1109,  0.7918, -0.3026,  0.3129, -0.0502,  0.25]),
 array([-7.,  0.,  3., -3.,  4., -0.,  0.]))

矢量化数组运算

如果要进行数组之间的运算,罕用的办法就是进行循环遍历,然而这样的效率会比拟低。所以 Numpy 提供了数组之间的数据处理的办法。

先来解说一下 np.meshgrid 这个函数,这个函数是用来疾速生成网格点坐标矩阵的。

先看一段坐标点的代码:

import numpy as np
import matplotlib.pyplot as plt

x = np.array([[0, 1, 2], [0, 1, 2]])
y = np.array([[0, 0, 0], [1, 1, 1]])


plt.plot(x, y,
         color='green',
         marker='.',
         linestyle='')
plt.grid(True)
plt.show()

下面的 X 是一个二维数组,示意的是坐标点的 X 轴的地位。

Y 也是一个二维数组,示意的是坐标点的 Y 轴的地位。

看下画进去的图像:

下面画出的就是应用 X,Y 矩阵组合进去的 6 个坐标点。

下面的 X,Y 的二维数组是咱们手动输出的,如果坐标下面有大量点的话,手动输出必定是不可取的。

于是有了 np.meshgrid 这个函数。这个函数能够承受两个一维的数组,而后生成二维的 X,Y 坐标矩阵。

下面的例子能够改写为:

x = np.array([0,1,2])
y = np.array([0,1])

xs, ys = np.meshgrid(x, y)
xs,ys
(array([[0, 1, 2],
        [0, 1, 2]]), 
 array([[0, 0, 0],
        [1, 1, 1]]))

能够看到生成的 xs 和 ys 和手动输出是一样的。

有了网格坐标之后,咱们就能够基于网格值来计算一些数据,比方:$sqrt(x^2+y^2)$,咱们不必变量矩阵中所有的数据,只须要间接应用数组进行运算即可:

np.sqrt(xs ** 2 + ys ** 2)

后果:

array([[0.        , 1.        , 2.],
       [1.        , 1.41421356, 2.23606798]])

因为 xs 和 ys 自身就是 2 3 的矩阵,所以后果也是 2 3 的矩阵。

条件逻辑表达式

咱们能够在构建数组的时候应用条件逻辑表达式:

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 = [(x if c else y)
          for x, y, c in zip(xarr, yarr, cond)]
result
[1.1, 2.2, 1.3, 1.4, 2.5]

更简略一点,咱们能够应用 where 语句:

result = np.where(cond, xarr, yarr)
result
array([1.1, 2.2, 1.3, 1.4, 2.5])

咱们还能够依据 where 的条件来批改数组的值:

arr = np.random.randn(4, 4)
arr
array([[0.7953,  0.1181, -0.7485,  0.585],
       [0.1527, -1.5657, -0.5625, -0.0327],
       [-0.929 , -0.4826, -0.0363,  1.0954],
       [0.9809, -0.5895,  1.5817, -0.5287]])

下面咱们构建了一个 4 * 4 的数组。

咱们能够在 where 中进行数据的比拟,如果大于 0,将数据批改成 2,如果小于 0,则将数据修该成 -2:

np.where(arr > 0, 2, -2)
array([[2,  2, -2,  2],
       [2, -2, -2, -2],
       [-2, -2, -2,  2],
       [2, -2,  2, -2]])

统计办法

numpy 提供了 mean,sum 等统计办法:

arr = np.random.randn(5, 4)
arr
arr.mean()
np.mean(arr)
arr.sum()

还能够按维度来统计:

arr.mean(axis=1)
arr.sum(axis=0)

cumsum 进行累加计算:

arr = np.array([0, 1, 2, 3, 4, 5, 6, 7])
arr.cumsum()
array([0,  1,  3,  6, 10, 15, 21, 28])

cumprod 进行累乘计算:

arr = np.array([[0, 1, 2], [3, 4, 5], [6, 7, 8]])
arr
arr.cumsum(axis=0)
array([[0,  1,  2],
       [3,  5,  7],
       [9, 12, 15]])
arr.cumprod(axis=1)
array([[0,   0,   0],
       [3,  12,  60],
       [6,  42, 336]])

布尔数组

any 用于测试数组中是否存在一个或多个 True,而 all 则查看数组中所有值是否都是 True:

bools = np.array([False, False, True, False])
bools.any()
True
bools.all()
False

排序

应用 sort 能够对数组进行排序,除了一般排序还能够依照特定的轴来进行排序:

arr = np.random.randn(6)
arr.sort()
array([-2.5579, -1.2943, -0.2972, -0.1516,  0.0765,  0.1608])
arr = np.random.randn(5, 3)
arr
arr.sort(1)
arr
array([[-0.8852, -0.4936, -0.1875],
       [-0.3507, -0.1154,  0.0447],
       [-1.1512, -0.8978,  0.8909],
       [-2.6123, -0.8671,  1.1413],
       [-0.437 ,  0.3475,  0.3836]])

sort(1)指的是依照第二个轴来排序。

文件

能够不便的将数组写入到文件和从文件中读出:

arr = np.arange(10)
np.save('some_array', arr)

会将数组寄存到 some_array.npy 文件中,咱们能够这样读取:

np.load('some_array.npy')

还能够以无压缩的形式存入多个数组:

np.savez('array_archive.npz', a=arr, b=arr)

读取:

arch = np.load('array_archive.npz')
arch['b']

如果想要压缩,能够这样:

np.savez_compressed('arrays_compressed.npz', a=arr, b=arr)

线性代数

如果咱们应用一般的算数符来进行矩阵的运算的话,只是简略的数组中对应的元素的算数运算。如果咱们想做矩阵之间的乘法的时候,能够应用 dot。

一个 2 3 的矩阵 dot 一个 3 2 的矩阵,最终失去一个 2 * 2 的矩阵。

x = np.array([[1., 2., 3.], [4., 5., 6.]])
y = np.array([[6., 23.], [-1, 7], [8, 9]])
x
y
x.dot(y)
array([[28.,  64.],
       [67., 181.]])

或者能够这样写:

np.dot(x, y)
array([[28.,  64.],
       [67., 181.]])

还能够应用 @ 符号:

x @ y
array([[28.,  64.],
       [67., 181.]])

咱们看下都有哪些运算:

乘积运算:

操作符 形容
dot(a, b[, out]) 矩阵点积
linalg.multi_dot(arrays, *[, out]) 多个矩阵点积
vdot(a, b) 向量点积
inner(a, b) 两个数组的内积
outer(a, b[, out]) 两个向量的外积
matmul(x1, x2, /[, out, casting, order, …]) 两个矩阵的对应位的乘积
tensordot(a, b[, axes]) 计算沿指定轴的张量点积
einsum(subscripts, *operands[, out, dtype, …]) 爱因斯坦 求和约定
einsum_path(subscripts, *operands[, optimize]) 通过思考两头数组的创立,评估 einsum 表达式的最低老本膨胀程序。
linalg.matrix_power(a, n) 矩阵的幂运算
kron(a, b) 矩阵的 Kronecker 乘积

合成运算:

操作符 形容
linalg.cholesky(a) Cholesky 合成
linalg.qr(a[, mode]) 计算矩阵的 qr 因式分解
linalg.svd(a[, full_matrices, compute_uv, …]) 奇怪值合成

本征值和本征向量:

操作 形容
linalg.eig(a) 计算方阵的特征值和右特征向量。
linalg.eigh(a[, UPLO]) 返回复数 Hermitian(共轭对称)或实对称矩阵的特征值和特征向量。
linalg.eigvals(a) 计算通用矩阵的特征值。
linalg.eigvalsh(a[, UPLO]) 计算复数 Hermitian(共轭对称)或实对称矩阵的特征值。

基准值:

操作 形容
linalg.norm(x[, ord, axis, keepdims]) 矩阵或向量范数
linalg.cond(x[, p]) Compute the condition number of a matrix.
linalg.det(a) 矩阵行列式
linalg.matrix_rank(M[, tol, hermitian]) 应用 SVD 办法返回数组的矩阵秩
linalg.slogdet(a) 计算数组行列式的符号和(天然)对数。
trace(a[, offset, axis1, axis2, dtype, out]) 返回沿数组对角线的和。

求解和反转:

操作 形容
linalg.solve(a, b) 求解线性矩阵方程或线性标量方程组。
linalg.tensorsolve(a, b[, axes]) 对 x 求解张量方程 ’a x = b’。
linalg.lstsq(a, b[, rcond]) 将最小二乘解返回线性矩阵方程
linalg.inv(a) 计算矩阵的(乘法)逆。
linalg.pinv(a[, rcond, hermitian]) 计算矩阵的(Moore-Penrose)伪逆。
linalg.tensorinv(a[, ind]) 计算 N 维数组的“逆”。

随机数

很多时候咱们都须要生成随机数,在 NumPy 中随机数的生成非常简单:

samples = np.random.normal(size=(4, 4))
samples
array([[-2.0016, -0.3718,  1.669 , -0.4386],
       [-0.5397,  0.477 ,  3.2489, -1.0212],
       [-0.5771,  0.1241,  0.3026,  0.5238],
       [0.0009,  1.3438, -0.7135, -0.8312]])

下面用 normal 来失去一个规范正态分布的 4×4 样本数组。

应用 np.random 要比应用 Python 自带的随机数生成器要快得多。

np.random 能够指定生成随机数的种子:

np.random.seed(1234)

numpy.random 的数据生成函数应用了全局的随机种子。要防止 全局状态,你能够应用 numpy.random.RandomState,创立一个 与其它隔离的随机数生成器:

rng = np.random.RandomState(1234)
rng.randn(10)

本文已收录于 http://www.flydean.com/10-python-numpy-func/

最艰深的解读,最粗浅的干货,最简洁的教程,泛滥你不晓得的小技巧等你来发现!

欢送关注我的公众号:「程序那些事」, 懂技术,更懂你!

正文完
 0