📜  numpy 备忘单 (1)

📅  最后修改于: 2023-12-03 15:18:03.152000             🧑  作者: Mango

NumPy 备忘单

NumPy 是一个用于科学计算的 Python 库。它提供了支持大型、多维数组和矩阵的数据结构,以及相应的计算函数,让我们能够轻松地进行数值计算。本文将提供一份常用的 NumPy 备忘单,以便于程序员的日常使用。

导入 NumPy

在使用 NumPy 之前,需要先进行导入。在 Python 中,约定俗称的导入 NumPy 的方式是:

import numpy as np

这句代码将导入 NumPy 库,并使用缩写 np 代替 numpy。

创建数组

我们可以使用 NumPy 数组来代替 Python 中的列表,创建一个 NumPy 数组的方式有以下几种:

从列表创建
a = np.array([1, 2, 3])
print(a)
[1 2 3]
创建特定大小的数组
a = np.zeros((2, 2))  # 注意这里的参数是一个元组
print(a)
[[0. 0.]
 [0. 0.]]
a = np.ones((2, 2))
print(a)
[[1. 1.]
 [1. 1.]]
a = np.full((2, 2), 7)
print(a)
[[7 7]
 [7 7]]
创建随机数组
a = np.random.random((2, 2))
print(a)
[[0.10664288 0.20594742]
 [0.59639431 0.60481913]]
a = np.random.randint(0, 10, (2, 2))
print(a)
[[6 9]
 [8 8]]
数组索引

访问 NumPy 数组中的元素,支持切片和索引,并且使用的是 0-based 索引。

a = np.array([1, 2, 3, 4])
print(a[0], a[1], a[-1])
1 2 4
a[0] = 5
print(a)
[5 2 3 4]
b = np.array([[1, 2, 3], [4, 5, 6]])
print(b[0, 0], b[0, 1], b[1, 2])
1 2 6
数组切片

切片是指从原数组中获取连续的一个子数组。可以通过“:”符号指定切片的范围,例如 a[1:4]。注意,这个范围是左闭右开的,即包含起点但不包含终点。

a = np.array([1, 2, 3, 4, 5])
print(a[1:4])
[2 3 4]
b = np.array([[1, 2, 3], [4, 5, 6], [7, 8, 9]])
print(b[:2, 1:])
[[2 3]
 [5 6]]
数组计算

NumPy 支持一些常用的数组计算方式,例如逐元素加减和向量点积等。

x = np.array([1, 2, 3])
y = np.array([4, 5, 6])
print(x + y)
[5 7 9]
a = np.array([[1, 2], [3, 4]])
b = np.array([[5, 6], [7, 8]])
print(a.dot(b))
[[19 22]
 [43 50]]
print(np.sum(a))  # 所有元素求和
print(np.sum(a, axis=0))  # 按列求和
print(np.sum(a, axis=1))  # 按行求和
10
[4 6]
[3 7]
Broadcasting 广播

广播是 NumPy 中一种重要的机制,它允许不同形状的数组之间进行算术操作。具体原则如下:

  1. 如果两个数组的维数不同,将小维数的数组进行扩展,使其维数和大数组一样。
  2. 如果两个数组在某个维度上大小不同,可以按照以下原则进行扩展:
    • 如果一个数组在该维度上的大小为 1,而另一个数组在该维度上的大小不为 1,那么可以看做是在该维度上“扩展”数据。
    • 如果两个数组在某个维度上的大小都不为 1,但是大小不同,那么会抛出错误。
a = np.array([1, 2, 3])
b = 2
print(a * b)
[2 4 6]
a = np.array([[1, 2, 3], [4, 5, 6]])
b = np.array([1, 2, 3])
print(a + b)
[[2 4 6]
 [5 7 9]]
a = np.array([[1, 2, 3], [4, 5, 6]])
b = np.array([[1], [2]])
print(a + b)
[[2 3 4]
 [6 7 8]]
运算优化

对于一些复杂的操作,NumPy 提供了许多优化的做法,可以更加高效地运行计算。以下是一些常用的技巧:

向量化

向量化是将循环体操作转换为向量之间的操作的过程。它使用 NumPy 数组代替循环体,使得代码更简洁高效。

a = np.array([1, 2, 3, 4, 5])
b = np.array([2, 2, 2, 2, 2])
%timeit a * b
%timeit [a[i] * b[i] for i in range(len(a))]
1.09 µs ± 29.3 ns per loop (mean ± std. dev. of 7 runs, 1000000 loops each)
3.14 µs ± 55 ns per loop (mean ± std. dev. of 7 runs, 100000 loops each)
使用 ufunc

ufunc(Universal Functions)是一类能够对数组进行逐元素操作的函数,是 NumPy 中一种优化的技巧。

import math

a = np.array([0, math.pi/2, math.pi])
print(np.sin(a))
[0.00000000e+00 1.00000000e+00 1.22464680e-16]
向量化聚合操作

聚合是指对数组中的若干元素执行某个操作,获得一个标量结果的过程。NumPy 中的聚合操作可以使用 ufunc 或者一些 NumPy 的内置函数。

a = np.array([1, 2, 3, 4, 5])
print(np.sum(a))
print(np.max(a))
print(np.min(a))
print(np.mean(a))
print(np.median(a))
print(np.std(a))
15
5
1
3.0
3.0
1.4142135623730951
总结

本文提供了一份常用的 NumPy 备忘单,包括数组创建、数组索引和切片、数组计算、广播、优化等几个方面。这份备忘单并不一定完全包括了 NumPy 中的所有知识点,但可以帮助程序员更加方便地进行科学计算。