介绍
来源:Numpy官网:https://numpy.org/doc/stable/user/basics.html
文章目录
- 介绍
- 导包
- 【1】将Python序列转换为Numpy数组
- 【2】通过已有的Numpy数组创建函数创建数组
- 【3】复制、连接或者改变现有数组
- 【4】从磁盘读取数组
- 【5】使用字符串或缓冲区从原始字节创建数组
- 【6】使用特殊的库函数
创建数组有 6 种常规机制:
- 从其他 Python 结构(即列表和元组)转换
- 内部 NumPy 数组创建函数(arange, ones, zeros 等)
- 复制、联接或改变现有数组
- 从磁盘读取阵列,无论是标准格式还是自定义格式
- 通过使用字符串或缓冲区从原始字节创建数组
- 使用特殊库功能(比如random)
导包
import numpy as np
【1】将Python序列转换为Numpy数组
NumPy数组可以使用Python序列(如列表和元组)进行定义。列表和元组分别使用 […] 和 (…) 定义。列表和元组可以定义 ndarray 创建:
数字列表将创建一个一维数组,
列表的列表将创建一个 2D 数组,
进一步嵌套的列表将创建更高维的数组。通常,任何数组对象在 NumPy 中都称为 ndarray。
a1D = np.array([1, 2, 3, 4])
a2D = np.array([[1, 2], [3, 4]])
a3D = np.array([[[1, 2], [3, 4]], [[5, 6], [7, 8]]])
print(a1D)
[1 2 3 4]
print(a2D)
[[1 2]
[3 4]]
print(a3D)
[[[1 2]
[3 4]]
[[5 6]
[7 8]]]
使用 numpy.array 定义新数组时,应考虑数组中元素的 dtype,可以显式指定。
如果你不小心dtype赋值,你可能会得到不需要的溢出
a = np.array([127, 128, 129], dtype=np.int8)
print(a)
[ 127 -128 -127]
8 位有符号整数表示从 -128 到 127 的整数。将 int8 数组分配给此范围之外的整数会导致溢出。
a = np.array([2, 3, 4], dtype=np.uint32)
b = np.array([5, 6, 7], dtype=np.uint32)
print(a)
[2 3 4]
print(b)
[5 6 7]
c_unsigned32 = a - b
print(c_unsigned32) ## 这是无符号的情况
[4294967293 4294967293 4294967293]
c_unsigned32.dtype
dtype('uint32')
c_signed32 = a - b.astype(np.int32)
print(c_signed32)
[-3 -3 -3]
c_signed32.dtype
dtype('int64')
注意,当您对两个相同 dtype 的数组执行操作时:uint32,生成的数组是相同的类型。
当你使用不同的dtype执行操作时,NumPy将分配一个新的类型,该类型满足计算中涉及的所有数组元素,这里uint32都可以表示为int64 int32.
如果希望整数数组是特定类型,一定在创建数组时指定 dtype。
【2】通过已有的Numpy数组创建函数创建数组
NumPy 具有 40 多个内置函数,用于创建数组。这些函数可以根据它们创建的数组的维度大致分为三类:
- 一维数组
- 二维数组
- 多维数组ndarrays
① 一维数组创建函数
numpy.arange 创建具有固定递增值的数组【最佳用法:arange(start , stop ,step)】
print(np.arange(10))
[0 1 2 3 4 5 6 7 8 9]
print(np.arange(2, 10, dtype=float))
[2. 3. 4. 5. 6. 7. 8. 9.]
print(np.arange(2, 3, 0.1))
[2. 2.1 2.2 2.3 2.4 2.5 2.6 2.7 2.8 2.9]
在第三个示例中,数组为 dtype=float 以适应 0.1 的步长。由于舍入误差,有时会包括stop值。
numpy.linspace 将创建具有指定数量元素的数组,并在指定的开始值和结束值之间平均间隔。
print(np.linspace(1., 4., 6))
[1. 1.6 2.2 2.8 3.4 4. ]
此创建功能的优点是可以保证元素的数量以及起点和终点。前一个arange(start, stop, step)将不包括stop.
② 二维数组创建函数
np.eye(n, m) 定义了一个 2D 单位矩阵。其中 i=j(行索引和列索引相等)的元素为 1,其余元素为 0
print(np.eye(3))
[[1. 0. 0.]
[0. 1. 0.]
[0. 0. 1.]]
print(np.eye(3, 5))
[[1. 0. 0. 0. 0.]
[0. 1. 0. 0. 0.]
[0. 0. 1. 0. 0.]]
numpy.diag 可以定义一个沿对角线具有给定值的方形 2D 数组,或者如果给定一个 2D 数组,则返回一个仅是对角线元素的一维数组。
print(np.diag([1, 2, 3]))
[[1 0 0]
[0 2 0]
[0 0 3]]
print(np.diag([1, 2, 3], 1)) # 上移
[[0 1 0 0]
[0 0 2 0]
[0 0 0 3]
[0 0 0 0]]
print(np.diag([1, 2, 3], -1)) # 下移
[[0 0 0 0]
[1 0 0 0]
[0 2 0 0]
[0 0 3 0]]
a = np.array([[1, 2], [3, 4]])
print(a)
[[1 2]
[3 4]]
print(np.diag(a)) ## 把二维数组的主对角线取出来了
[1 4]
vander(x, n) 将范德蒙德矩阵定义为 2D NumPy 数组。范德蒙德矩阵的每一列都是输入一维数组或列表或元组的递减x最高多项式阶数为 n-1。
V = [ 1 α 1 α 1 2 … α 1 n − 1 1 α 2 α 2 2 … α 2 n − 1 1 α 3 α 3 2 … α 3 n − 1 ⋮ ⋮ ⋮ ⋱ ⋮ 1 α m α m 2 … α m n − 1 ] V=\left[\begin{array}{ccccc} 1 & \alpha_1 & \alpha_1^2 & \ldots & \alpha_1^{n-1} \\ 1 & \alpha_2 & \alpha_2^2 & \ldots & \alpha_2^{n-1} \\ 1 & \alpha_3 & \alpha_3^2 & \ldots & \alpha_3^{n-1} \\ \vdots & \vdots & \vdots & \ddots & \vdots \\ 1 & \alpha_m & \alpha_m^2 & \ldots & \alpha_m^{n-1} \end{array}\right] V=⎣⎢⎢⎢⎢⎢⎡111⋮1α1α2α3⋮αmα12α22α32⋮αm2………⋱…α1n−1α2n−1α3n−1⋮αmn−1⎦⎥⎥⎥⎥⎥⎤
print(np.vander(np.linspace(0, 2, 5), 2))
[[0. 1. ]
[0.5 1. ]
[1. 1. ]
[1.5 1. ]
[2. 1. ]]
print(np.vander([1, 2, 3, 4], 2))
[[1 1]
[2 1]
[3 1]
[4 1]]
print(np.vander((1, 2, 3, 4), 4))
[[ 1 1 1 1]
[ 8 4 2 1]
[27 9 3 1]
[64 16 4 1]]
此数组创建方式有助于生成线性最小二乘模型
③ 常规ndarray 创建函数
numpy.zeros 将创建一个填充 0 值的数组,具有指定的形状。默认 dtype 为 float64:
print(np.zeros((2, 3)))
[[0. 0. 0.]
[0. 0. 0.]]
np.zeros((2, 3)).dtype
dtype('float64')
print(np.zeros((2, 3, 2)))
[[[0. 0.]
[0. 0.]
[0. 0.]]
[[0. 0.]
[0. 0.]
[0. 0.]]]
numpy.ones 将创建一个填充 1 个值的数组。它在所有其他方面都与zeros相同:
print(np.ones((2, 3)))
[[1. 1. 1.]
[1. 1. 1.]]
print(np.ones((2, 3, 2)))
[[[1. 1.]
[1. 1.]
[1. 1.]]
[[1. 1.]
[1. 1.]
[1. 1.]]]
default_rng结果的random方法将创建一个填充 0 到 1 之间的随机值的数组。它包含在numpy.random库中。
from numpy.random import default_rng
print(default_rng(42).random((2, 3)))
[[0.77395605 0.43887844 0.85859792]
[0.69736803 0.09417735 0.97562235]]
print(default_rng(42).random((2, 3, 2)))
[[[0.77395605 0.43887844]
[0.85859792 0.69736803]
[0.09417735 0.97562235]]
[[0.7611397 0.78606431]
[0.12811363 0.45038594]
[0.37079802 0.92676499]]]
这就是伪随机
numpy.indices 将创建一组数组(堆叠为一个更高维度的数组),每个维度一个,每个维度代表该维度的变体:
print(np.indices((3, 3)))
[[[0 0 0]
[1 1 1]
[2 2 2]]
[[0 1 2]
[0 1 2]
[0 1 2]]]
【3】复制、连接或者改变现有数组
创建数组后,可以复制、联接或更改这些现有数组以创建新数组。
将数组或其元素分配给新变量时,必须显式 numpy.copy 数组,否则变量是原始数组的视图。
a = np.array([1, 2, 3, 4, 5, 6])
print(a)
[1 2 3 4 5 6]
b = a[:2].copy()
print(b)
[1 2]
b += 1
print(b)
[2 3]
print(a)
[1 2 3 4 5 6]
copy深拷贝, 对拷贝出来的数组的操作不会影响原数组
有许多方法可以连接现有数组,例如numpy.vstack,numpy.hstack和numpy.vstacknumpy.hstack。numpy.block
使用block将四个 2 x 2 数组连接到 4 x 4 数组
A = np.ones((2, 2))
B = np.eye(2, 2)
C = np.zeros((2, 2))
D = np.diag((-3, -4))
print(A)
[[1. 1.]
[1. 1.]]
print(B)
[[1. 0.]
[0. 1.]]
print(C)
[[0. 0.]
[0. 0.]]
print(D)
[[-3 0]
[ 0 -4]]
print(np.block([[A, B], [C, D]]))
[[ 1. 1. 1. 0.]
[ 1. 1. 0. 1.]
[ 0. 0. -3. 0.]
[ 0. 0. 0. -4.]]
【4】从磁盘读取数组
这是创建大型数组的最常见情况。详细信息在很大程度上取决于磁盘上数据的格式。
① 标准二进制格式
各种字段具有数组数据的标准格式。下面列出了具有已知 Python 库的那些来读取它们并返回 NumPy 数组
HDF5: h5py
FITS: Astropy
② 常见的ASCII格式
逗号分隔值 (csv) 和制表符分隔值 (tsv) 文件等分隔文件用于 Excel 和 LabView 等程序。
一个简单的例子给出了simple.csv:【见文件】
导入simple.csv是使用 loadtxt 完成的:
print(np.loadtxt("simple.csv", delimiter=',', skiprows=1))
[[0. 0.]
[1. 1.]
[2. 4.]
[3. 9.]]
可以使用 scipy.io 和Pandas读取更通用的ASCII文件.
【5】使用字符串或缓冲区从原始字节创建数组
可以使用多种方法。如果文件具有相对简单的格式,则可以编写一个简单的I / O库,并使用NumPy fromfile()()函数和.tofile()方法直接读取和写入NumPy数组(请注意您的字节顺序!如果存在一个读取数据的好的 C 或 C++ 库,则可以使用各种技术包装该库,尽管这肯定需要更多的工作,并且需要更高级的知识才能与 C 或 C++ 接口【官方文档没有给栗子… 用的应该比较少】
【6】使用特殊的库函数
NumPy是Python Scientific Computing堆栈中数组容器的基本库。许多Python库,包括SciPy,Pandas和OpenCV,使用NumPyndarrays作为数据交换的通用格式,这些库可以创建,操作和使用NumPy数组。