NumPy-1-26-中文文档-二-
NumPy 1.26 中文文档(二)
基础与用法
NumPy 基础知识
这些文档阐明了 NumPy 中的概念、设计决策和技术限制。这是了解 NumPy 基本思想和哲学的好地方。
-
数组创建
-
对
ndarrays进行索引 -
使用 NumPy 进行 I/O
-
数据类型
-
广播
-
复制和视图
-
结构化数组
-
通用函数(
ufunc)基础知识
MATLAB 用户的 NumPy
介绍
MATLAB® 和 NumPy 有很多共同之处,但 NumPy 是为了与 Python 一起使用而创建的,而不是 MATLAB 的克隆。本指南将帮助 MATLAB 用户开始使用 NumPy。
一些主要区别
| 在 MATLAB 中,即使对于标量,基本类型也是多维数组。在 MATLAB 中的数组赋值都以双精度浮点数的 2D 数组存储,除非你指定维数和类型。对这些数组的 2D 实例的操作都是模仿线性代数中的矩阵操作。 | 在 NumPy 中,基本类型是多维数组。在 NumPy 中的数组赋值通常存储为 n 维数组,只需要最小类型来存储对象,除非你指定维数和类型。NumPy 执行元素按元素的操作,所以用*来乘以 2D 数组不是矩阵乘法 - 这是元素按元素的乘法。(自 Python 3.5 开始,可以使用@运算符进行传统的矩阵乘法。) |
|---|---|
MATLAB 数字从 1 开始索引;a(1) 是第一个元素。参见说明 索引 |
NumPy,与 Python 一样,数字从 0 开始索引;a[0] 是第一个元素。 |
| MATLAB 的脚本语言是为了线性代数而创建的,因此一些数组操作的语法比 NumPy 更紧凑。另一方面,添加 GUI 和创建完整的应用程序的 API 更多或多或少是事后想法。 | NumPy 是基于 Python 的通用语言。NumPy 的优势在于访问 Python 库,包括:SciPy,Matplotlib,Pandas,OpenCV等。此外,Python 经常作为嵌入式脚本语言嵌入到其他软件中,也可以在那里使用 NumPy。 |
| MATLAB 数组切片使用值传递语义,采用延迟写入复制方案以防止创建副本,直到需要为止。切片操作复制数组的部分。 | NumPy 数组切片使用按引用传递的方式,不复制参数。切片操作是对数组的视图。 |
大致等效项
下表提供了一些常见 MATLAB 表达式的大致等效项。这些是类似的表达式,而不是等效项。详情请参见文档。
在下表中,假设你已经在 Python 中执行了以下命令:
import numpy as np
from scipy import io, integrate, linalg, signal
from scipy.sparse.linalg import cg, eigs
还假设如果备注谈论“矩阵”,那么参数是二维实体。
通用等效物
| MATLAB | NumPy | 说明 |
|---|---|---|
help func |
info(func) 或 help(func) 或 func?(在 IPython 中) |
获取关于函数 func 的帮助信息 |
which func |
参见注释 HELP | 找出 func 的定义位置 |
type func |
np.source(func) 或 func??(在 IPython 中) |
输出 func 的源代码(如果不是原生函数) |
% comment |
# comment |
在代码行中注释文本comment |
|
for i=1:3
fprintf('%i\n',i)
end
|
for i in range(1, 4):
print(i)
使用 for 循环使用 range 打印数字 1, 2 和 3 |
|---|
a && b |
a || b |
|
>> 4 == 4
ans = 1
>> 4 == 5
ans = 0
|
>>> 4 == 4
True
>>> 4 == 5
False
Python 中的布尔对象为 True 和 False,而不是 MATLAB 的逻辑类型 1 和 0。 |
|---|
|
a=4
if a==4
fprintf('a = 4\n')
elseif a==5
fprintf('a = 5\n')
end
|
a = 4
if a == 4:
print('a = 4')
elif a == 5:
print('a = 5')
创建一个 if-else 语句来检查 a 是否为 4 或 5 并打印结果 |
|---|
1*i, 1*j, 1i, 1j |
eps |
load data.mat |
ode45 |
ode15s |
线性代数等价操作
| MATLAB | NumPy | 备注 |
|---|---|---|
ndims(a) |
np.ndim(a) 或 a.ndim |
数组 a 的维数 |
numel(a) |
np.size(a) 或 a.size |
数组 a 的元素数量 |
size(a) |
np.shape(a) 或 a.shape |
数组 a 的“大小” |
size(a,n) |
a.shape[n-1] |
获取数组 a 的第 n 维的元素数量。(注意 MATLAB 使用基于 1 的索引,而 Python 使用基于 0 的索引,参见 INDEXING 注释) |
[ 1 2 3; 4 5 6 ] |
np.array([[1., 2., 3.], [4., 5., 6.]]) |
定义一个 2x3 的二维数组 |
[ a b; c d ] |
np.block([[a, b], [c, d]]) |
从块 a, b, c 和 d 构建矩阵 |
a(end) |
a[-1] |
访问 MATLAB 向量(1xn 或 nx1)或 1D NumPy 数组 a(长度 n)中的最后一个元素 |
a(2,5) |
a[1, 4] |
访问二维数组 a 中第二行第五列的元素 |
a(2,:) |
a[1] 或 a[1, :] |
二维数组 a 的整个第二行 |
a(1:5,:) |
a[0:5] 或 a[:5] 或 a[0:5, :] |
二维数组 a 的前 5 行 |
a(end-4:end,:) |
a[-5:] |
二维数组 a 的最后 5 行 |
a(1:3,5:9) |
a[0:3, 4:9] |
二维数组 a 的前三行和第五至第九列 |
a([2,4,5],[1,3]) |
a[np.ix_([1, 3, 4], [0, 2])] |
第 2、4 和 5 行以及第 1 和 3 列。这样可以修改矩阵,而且不需要常规切片。 |
a(3:2:21,:) |
a[2:21:2,:] |
a 的每两行,从第三行开始到第二十一行 |
a(1:2:end,:) |
a[::2, :] |
a 的每两行,从第一行开始 |
a(end:-1:1,:) 或 flipud(a) |
a[::-1,:] |
a 的行顺序反转 |
a([1:end 1],:) |
a[np.r_[:len(a),0]] |
a 的复制,将第一行附加到末尾 |
a.' |
a.transpose() 或 a.T |
a 的转置 |
a' |
a.conj().transpose() 或 a.conj().T |
a 的共轭转置 |
a * b |
a @ b |
矩阵相乘 |
a .* b |
a * b |
逐元素相乘 |
a./b |
a/b |
逐元素除 |
a.³ |
a**3 |
逐元素求幂 |
(a > 0.5) |
(a > 0.5) |
矩阵的第 i,j 个元素为 (a_ij > 0.5)。MATLAB 的结果是逻辑值 0 和 1 的数组。NumPy 的结果是布尔值 False 和 True 的数组。 |
find(a > 0.5) |
np.nonzero(a > 0.5) |
找出 (a > 0.5) 的索引 |
a(:,find(v > 0.5)) |
a[:,np.nonzero(v > 0.5)[0]] |
提取 a 中向量 v > 0.5 的列 |
a(:,find(v>0.5)) |
a[:, v.T > 0.5] |
提取 a 中列向量 v > 0.5 的列 |
a(a<0.5)=0 |
a[a < 0.5]=0 |
a 中小于 0.5 的元素清零 |
a .* (a>0.5) |
a * (a > 0.5) |
a 中小于 0.5 的元素清零 |
a(:) = 3 |
a[:] = 3 |
将所有值设为相同的标量值 |
y=x |
y = x.copy() |
NumPy 通过引用进行赋值 |
y=x(2,:) |
y = x[1, :].copy() |
NumPy 切片是引用传递的 |
y=x(:) |
y = x.flatten() |
将数组转换为向量(注意这会强制进行一次复制)。要获得与 MATLAB 相同的数据顺序,使用 x.flatten('F')。 |
1:10 |
np.arange(1., 11.) 或 np.r_[1.:11.] 或 np.r_[1:10:10j] |
创建递增向量(见注释 RANGES) |
0:9 |
np.arange(10.) 或 np.r_[:10.] 或 np.r_[:9:10j] |
创建递增向量(见注释 RANGES) |
[1:10]' |
np.arange(1.,11.)[:, np.newaxis] |
创建列向量 |
zeros(3,4) |
np.zeros((3, 4)) |
64 位浮点 0 组成的 3x4 二维数组 |
zeros(3,4,5) |
np.zeros((3, 4, 5)) |
64 位浮点 0 组成的 3x4x5 三维数组 |
ones(3,4) |
np.ones((3, 4)) |
64 位浮点 1 组成的 3x4 二维数组 |
eye(3) |
np.eye(3) |
3x3 单位矩阵 |
diag(a) |
np.diag(a) |
返回二维数组 a 的对角元素向量 |
diag(v,0) |
np.diag(v, 0) |
返回一个正方形对角阵,其非零值是向量v的元素 |
|
rng(42,'twister')
rand(3,4)
|
from numpy.random import default_rng
rng = default_rng(42)
rng.random(3, 4)
或者旧版本:random.rand((3, 4)) | 用默认随机数生成器和 seed = 42 生成一个 3x4 的随机数组 |
linspace(1,3,4) |
np.linspace(1,3,4) |
在 1 和 3 之间生成 4 个等间距的样本,包括边界值 |
|---|---|---|
[x,y]=meshgrid(0:8,0:5) |
np.mgrid[0:9.,0:6.]或np.meshgrid(r_[0:9.],r_[0:6.]) |
两个二维数组:一个是 x 值,另一个是 y 值 |
ogrid[0:9.,0:6.]或np.ix_(np.r_[0:9.],np.r_[0:6.] |
在网格上评估函数的最佳方法 | |
[x,y]=meshgrid([1,2,4],[2,4,5]) |
np.meshgrid([1,2,4],[2,4,5]) |
|
np.ix_([1,2,4],[2,4,5]) |
在网格上评估函数的最佳方法 | |
repmat(a, m, n) |
np.tile(a, (m, n)) |
创建 m 行 n 列的a副本 |
[a b] |
np.concatenate((a,b),1)或np.hstack((a,b))或np.column_stack((a,b))或np.c_[a,b] |
连接a和b的列 |
[a; b] |
np.concatenate((a,b))或np.vstack((a,b))或np.r_[a,b] |
连接a和b的行 |
max(max(a)) |
a.max()或np.nanmax(a) |
a的最大元素(对于 MATLAB,如果存在 NaN 值,nanmax将忽略这些值并返回最大值) |
max(a) |
a.max(0) |
数组a每列的最大元素 |
max(a,[],2) |
a.max(1) |
数组a每行的最大元素 |
max(a,b) |
np.maximum(a, b) |
逐元素比较a和b,并返回每对中的最大值 |
norm(v) |
np.sqrt(v @ v)或np.linalg.norm(v) |
向量v的 L2 范数 |
a & b |
logical_and(a,b) |
逐元素的与运算符(NumPy ufunc)查看逻辑运算符注意事项 |
a | b |
np.logical_or(a,b) |
逐元素的或运算符(NumPy ufunc)查看逻辑运算符注意事项 |
bitand(a,b) |
a & b |
位与运算符(Python 原生和 NumPy ufunc) |
bitor(a,b) |
a | b |
位或运算符(Python 原生和 NumPy ufunc) |
inv(a) |
linalg.inv(a) |
二维方阵a的逆矩阵 |
pinv(a) |
linalg.pinv(a) |
二维数组a的伪逆矩阵 |
rank(a) |
np.linalg.matrix_rank(a) |
二维数组a的矩阵秩 |
a\b |
如果a是方阵,则linalg.solve(a, b);否则为linalg.lstsq(a, b) |
解方程a x = b |
b/a |
解a.T x.T = b.T |
解方程x a = b |
[U,S,V]=svd(a) |
U, S, Vh = linalg.svd(a); V = Vh.T |
a的奇异值分解 |
chol(a) |
linalg.cholesky(a) |
二维数组a的 Cholesky 分解 |
[V,D]=eig(a) |
D,V = linalg.eig(a) |
a的特征值(\lambda)和特征向量(v),其中(\mathbf{a} v = \lambda v) |
[V,D]=eig(a,b) |
D,V = linalg.eig(a, b) |
a, b的特征值(\lambda)和特征向量(v),其中(\mathbf{a} v = \lambda \mathbf{b} v) |
[V,D]=eigs(a,3) |
D,V = eigs(a, k=3) |
二维数组a的前k=3个最大特征值和特征向量 |
[Q,R]=qr(a,0) |
Q,R = linalg.qr(a) |
QR 分解 |
[L,U,P]=lu(a),其中 a==P'*L*U |
P,L,U = linalg.lu(a),其中 a == P@L@U |
带有部分主元选取的 LU 分解(注意:P(MATLAB)== transpose(P(NumPy))) |
conjgrad |
cg |
共轭梯度求解器 |
fft(a) |
np.fft.fft(a) |
数组 a 的傅里叶变换 |
ifft(a) |
np.fft.ifft(a) |
数组 a 的逆傅里叶变换 |
sort(a) |
np.sort(a) 或 a.sort(axis=0) |
对二维数组 a 的每一列进行排序 |
sort(a, 2) |
np.sort(a, axis=1) 或 a.sort(axis=1) |
对二维数组 a 的每一行进行排序 |
[b,I]=sortrows(a,1) |
I = np.argsort(a[:, 0]); b = a[I,:] |
将数组 a 按照第一列排序后保存为数组 b |
x = Z\y |
x = linalg.lstsq(Z, y) |
执行形如 (\mathbf{Zx}=\mathbf{y}) 的线性回归 |
decimate(x, q) |
signal.resample(x, np.ceil(len(x)/q)) |
用低通滤波进行下采样 |
unique(a) |
np.unique(a) |
数组 a 中唯一的数值 |
squeeze(a) |
a.squeeze() |
删除数组 a 的单元素维度。注意,MATLAB 始终返回 2D 或更高维度的数组,而 NumPy 返回 0D 或更高维度的数组 |
注意事项
子矩阵:可以使用索引列表和 ix_ 命令对子矩阵进行赋值。例如,对于二维数组 a,可以执行:ind=[1, 3]; a[np.ix_(ind, ind)] += 100。
HELP: Python 没有直接等价于 MATLAB 的 which 命令,但是 help 命令和 numpy.source 命令通常会列出函数所在的文件名。Python 还有一个 inspect 模块(使用 import inspect 导入),其中提供了一个 getfile 方法,该方法通常起作用。
INDEXING: MATLAB 使用基于 1 的索引,所以一个序列的初始元素索引为 1。Python 使用基于 0 的索引,所以一个序列的初始元素索引为 0。混淆和争议产生是因为每种方式都有优劣之处。基于 1 的索引与人们常用的自然语言使用方式一致,其中序列的“第一个”元素索引为 1。基于 0 的索引简化了索引操作。还可参考Edsger W. Dijkstra 教授的某篇文本。
RANGES:在 MATLAB 中,0:5 可以作为区间文字和“切片”索引使用(在圆括号内);然而,在 Python 中,形如 0:5 的结构只能作为“切片”索引使用(在方括号内)。因此,为了使 NumPy 具有类似简洁的区间构造机制,创建了有点古怪的 r_ 对象。注意,r_ 不像函数或构造函数一样调用,而是使用方括号进行索引,这允许在参数中使用 Python 的切片语法。
逻辑运算符:在 NumPy 中,&或|是按位 AND/OR 运算符,而在 MATLAB 中,&和|是逻辑 AND/OR 运算符。这两者看起来可能是相同的,但存在重要的区别。如果你曾经使用过 MATLAB 的&或|运算符,你应该使用 NumPy 的 ufuncs logical_and/logical_or。MATLAB 的&和|运算符与 NumPy 的&和|运算符之间的显着差异包括:
-
非逻辑{0,1}输入:NumPy 的输出是输入的按位 AND 运算。MATLAB 将任何非零值视为 1,并返回逻辑 AND。例如,在 NumPy 中
(3 & 4)是0,而在 MATLAB 中3和4都被视为逻辑真,(3 & 4)返回1。 -
优先级:NumPy 的&运算符的优先级高于诸如
<和>的逻辑运算符;MATLAB 的优先级相反。
如果你知道你有布尔参数,你可以使用 NumPy 的按位运算符,但要小心处理括号,就像这样:z = (x > 1) & (x < 2)。NumPy 没有logical_and和logical_or运算符形式是 Python 设计中不幸的结果。
重塑和线性索引:MATLAB 始终允许使用标量或线性索引来访问多维数组,NumPy 则不允许。线性索引在 MATLAB 程序中很常见,例如对矩阵进行find()操作返回它们,而 NumPy 的find()操作行为不同。在转换 MATLAB 代码时,可能需要首先将矩阵重塑为线性序列,进行一些索引操作,然后再重塑回去。由于重塑(通常)生成对存储空间的视图,因此应该可以相当有效地进行此操作。请注意,NumPy 中的 reshape 使用的扫描顺序默认为“C”顺序,而 MATLAB 使用 Fortran 顺序。如果你只是将其转换为线性序列并返回,这并不重要。但是,如果你要从依赖扫描顺序的 MATLAB 代码中转换重塑操作,那么此 MATLAB 代码:z = reshape(x,3,4);应该在 NumPy 中变成z = x.reshape(3,4,order='F').copy()。
‘array’或‘matrix’?我应该使用哪一个?
从历史角度来看,NumPy 提供了一个特殊的矩阵类型* np.matrix,它是 ndarray 的子类,可以进行二进制运算和线性代数运算。你可能会在一些现有代码中看到它的使用,而不是 np.array*。那么,应该使用哪一个?
简短回答
使用数组。
-
支持在 MATLAB 中支持的多维数组代数
-
它们是 NumPy 的标准向量/矩阵/张量类型。许多 NumPy 函数返回数组而不是矩阵。
-
在元素级运算和线性代数运算之间存在明显区别。
-
你可以拥有标准向量或行/列向量。
直到 Python 3.5 之前,使用数组类型的唯一劣势是你必须使用dot而不是*来对两个张量(标量积,矩阵向量乘法等)进行乘法运算。自 Python 3.5 以来,你可以使用矩阵乘法@运算符。
鉴于上述问题,我们打算最终弃用matrix。
长回答
NumPy 包含array类和matrix类。array类旨在为许多种数值计算提供通用的 n 维数组,而matrix类旨在特定的线性代数计算。实际上,这两者之间只有少数几个关键的区别。
-
运算符
*和@,函数dot()和multiply():-
对于
array,*表示逐元素相乘,而@表示矩阵乘法;它们有关联的函数multiply()和dot()。(在 Python 3.5 之前,@不存在,必须使用dot()进行矩阵乘法)。 -
对于
matrix,*表示矩阵乘法,对于逐元素相乘,必须使用multiply()函数。
-
-
处理向量(一维数组)
-
对于
array,形状为 1xN、Nx1 和 N 的向量是完全不同的。例如A[:,1]返回形状为 N 的一维数组,而不是形状为 Nx1 的二维数组。一维array的转置没有任何效果。 -
对于
matrix,一维数组始终被上转换为 1xN 或 Nx1 矩阵(行向量或列向量)。A[:,1]返回形状为 Nx1 的二维矩阵。
-
-
处理更高维度数组(ndim > 2)
-
array对象可以有大于 2 的维度; -
matrix对象始终具有确切的两个维度。
-
-
方便的属性
-
array具有.T 属性,返回数据的转置。 -
matrix还具有.H、.I 和.A 属性,分别返回矩阵的共轭转置、逆矩阵和 asarray()。
-
-
方便的构造函数
-
array构造函数以(嵌套)Python 序列作为初始化器。如,array([[1,2,3],[4,5,6]])。 -
matrix构造函数另外接受方便的字符串初始化器。如matrix("[1 2 3; 4 5 6]")。
-
使用两者都有利有弊:
-
array-
:)逐元素相乘很容易:A*B。 -
:(必须记住,矩阵乘法有自己的操作符@。 -
:)您可以将一维数组视为行向量或列向量。A @ v将v视为列向量,而v @ A将v视为行向量。这可以节省您的很多转置输入。 -
:)array是“默认”的 NumPy 类型,因此经过最多测试,并且是第三方使用 NumPy 的代码最有可能返回的类型。 -
:)可以很好地处理任意维度的数据。 -
:)如果你熟悉张量代数,:更接近语义。 -
:)所有操作(*,/,+,-等)都是逐元素的。 -
:(来自scipy.sparse的稀疏矩阵与数组的交互性不佳。
-
-
matrix-
:\\行为更像 MATLAB 的矩阵。 -
<:(最多为二维。要保存三维数据,您需要array或者可能是一个matrix的 Python 列表。 -
<:(最少为二维。不能有向量。它们必须被强制转换为单列或单行矩阵。 -
<:(由于array在 NumPy 中是默认值,一些函数可能返回一个array,即使你给它们一个matrix作为参数。这不应该发生在 NumPy 函数中(如果发生了,那是一个错误),但基于 NumPy 的第三方代码可能不会像 NumPy 那样遵守类型保留。 -
:)A*B是矩阵乘法,因此看起来就像您在线性代数中编写一样(对于 Python >= 3.5,普通数组使用@操作符具有相同的便利)。 -
<:(按元素相乘需要调用函数multiply(A,B)。 -
<:(操作符重载的使用有点不合逻辑:*不是按元素运行,但/是。 -
与
scipy.sparse的交互方式更清晰。
-
因此,使用array更加明智。的确,我们最终打算废弃matrix。
自定义您的环境
在 MATLAB 中,用于自定义环境的主要工具是修改搜索路径,包含您喜欢函数的位置。您可以将这种定制放入 MATLAB 将在启动时运行的启动脚本中。
NumPy,或者更确切地说是 Python,具有类似的功能。
-
要修改 Python 搜索路径以包括您自己模块的位置,请定义
PYTHONPATH环境变量。 -
要在启动交互式 Python 解释器时执行特定的脚本文件,请定义
PYTHONSTARTUP环境变量,其中包含您启动脚本的名称。
与 MATLAB 不同,在 Python 中,您需要首先执行一个‘import’语句来使特定文件中的函数可访问。
例如,您可以创建一个看起来像这样的启动脚本(注意:这只是一个例子,不是“最佳实践”的陈述):
# Make all numpy available via shorter 'np' prefix
import numpy as np
#
# Make the SciPy linear algebra functions available as linalg.func()
# e.g. linalg.lu, linalg.eig (for general l*B@u==A@u solution)
from scipy import linalg
#
# Define a Hermitian function
def hermitian(A, **kwargs):
return np.conj(A,**kwargs).T
# Make a shortcut for hermitian:
# hermitian(A) --> H(A)
H = hermitian
要使用不推荐使用的matrix和其他matlib函数:
# Make all matlib functions accessible at the top level via M.func()
import numpy.matlib as M
# Make some matlib functions accessible directly at the top level via, e.g. rand(3,3)
from numpy.matlib import matrix,rand,zeros,ones,empty,eye
链接
可以在mathesaurus.sf.net/找到另一个有些过时的 MATLAB/NumPy 交叉参考。
可以在专题软件页面中找到用于科学工作的 Python 的工具的广泛列表。
请参阅Python 软件列表:脚本以获取使用 Python 作为脚本语言的软件列表
MATLAB®和 SimuLink®是 The MathWorks,Inc.的注册商标。
介绍
MATLAB®和 NumPy 有很多共同之处,但 NumPy 是为了与 Python 一起工作而创建的,并不是 MATLAB 的克隆。本指南将帮助 MATLAB 用户开始使用 NumPy。
一些关键区别
| 在 MATLAB 中,即使是标量的基本类型也是多维数组。MATLAB 中的数组赋值存储为双精度浮点数的 2D 数组,除非你指定维数和类型。对这些数组的 2D 实例的操作是基于线性代数中的矩阵运算的。 | 在 NumPy 中,基本类型是多维array。NumPy 中的数组赋值通常存储为 n 维数组,以容纳序列中的对象所需的最小类型,除非你指定维数和类型。NumPy 执行逐个元素的操作,因此用*乘以 2D 数组不是矩阵乘法 - 而是逐个元素的乘法。(自 Python 3.5 以来可用的@运算符可以用于传统的矩阵乘法。) |
|---|---|
MATLAB 从 1 开始编号索引;a(1)是第一个元素。参见注释索引 |
NumPy,像 Python 一样,从 0 开始编号;a[0]是第一个元素。 |
| MATLAB 的脚本语言是为了线性代数而创建的,因此一些数组操作的语法比 NumPy 的更紧凑。另一方面,添加 GUI 和创建完整应用程序的 API 更多或多或少是事后想法。 | NumPy 基于 Python,这是一种通用语言。NumPy 的优势在于可以访问 Python 库,包括:SciPy,Matplotlib,Pandas,OpenCV等等。此外,Python 通常被嵌入为脚本语言到其他软件中,在那里也可以使用 NumPy。 |
| MATLAB 数组切片使用传值语义,具有延迟写入复制的机制,以防在需要之前创建副本。切片操作会复制数组的部分。 | NumPy 数组切片使用传址,不会复制参数。切片操作是对数组的视图。 |
大致的等价物
下表列出了一些常见 MATLAB 表达式的大致等价物。这些是相似的表达式,而不是等价物。详情请参见文档。
在下表中,假设你已在 Python 中执行了以下命令:
import numpy as np
from scipy import io, integrate, linalg, signal
from scipy.sparse.linalg import cg, eigs
还假设下面的附注说明了“矩阵”,即参数为二维实体。
通用目的的等价物
| MATLAB | NumPy | 注释 |
|---|---|---|
help func |
info(func)或help(func)或func?(在 IPython 中) |
获取函数func的帮助 |
which func |
参见注释帮助 | 查找func的定义位置 |
type func |
np.source(func)或func??(在 IPython 中) |
打印func的源代码(如果不是原生函数) |
% comment |
# comment |
用文本comment注释代码行 |
|
for i=1:3
fprintf('%i\n',i)
end
|
for i in range(1, 4):
print(i)
使用 for 循环使用 range 打印数字 1、2 和 3 |
|---|
a && b |
a || b |
|
>> 4 == 4
ans = 1
>> 4 == 5
ans = 0
|
>>> 4 == 4
True
>>> 4 == 5
False
Python 中的布尔对象是 True 和 False,不同于 MATLAB 的逻辑类型为 1 和 0。 |
|---|
|
a=4
if a==4
fprintf('a = 4\n')
elseif a==5
fprintf('a = 5\n')
end
|
a = 4
if a == 4:
print('a = 4')
elif a == 5:
print('a = 5')
创建一个 if-else 语句来检查 a 是否为 4 或 5 并打印结果 |
|---|
1*i, 1*j, 1i, 1j |
eps |
load data.mat |
ode45 |
ode15s |
线性代数的等价操作
| MATLAB | NumPy | 注释 |
|---|---|---|
ndims(a) |
np.ndim(a) 或 a.ndim |
数组 a 的维数 |
numel(a) |
np.size(a) 或 a.size |
数组 a 的元素个数 |
size(a) |
np.shape(a) 或 a.shape |
数组 a 的“大小” |
size(a,n) |
a.shape[n-1] |
获取数组 a 的第 n 维中的元素数。 (注意 MATLAB 使用基于 1 的索引,而 Python 使用基于 0 的索引,请参见 INDEXING) |
[ 1 2 3; 4 5 6 ] |
np.array([[1., 2., 3.], [4., 5., 6.]]) |
定义一个 2x3 的 2D 数组 |
[ a b; c d ] |
np.block([[a, b], [c, d]]) |
从块 a、b、c 和 d 构造一个矩阵 |
a(end) |
a[-1] |
访问 MATLAB 向量(1xn 或 nx1)或 1D NumPy 数组 a(长度为 n)中的最后一个元素 |
a(2,5) |
a[1, 4] |
访问 2D 数组 a 中第二行第五列的元素 |
a(2,:) |
a[1] 或 a[1, :] |
2D 数组 a 的整个第二行 |
a(1:5,:) |
a[0:5] 或 a[:5] 或 a[0:5, :] |
数组 a 的前 5 行 |
a(end-4:end,:) |
a[-5:] |
2D 数组 a 的最后 5 行 |
a(1:3,5:9) |
a[0:3, 4:9] |
2D 数组 a 的第一行到第三行和第五列到第九列 |
a([2,4,5],[1,3]) |
a[np.ix_([1, 3, 4], [0, 2])] |
第 2、4 和 5 行以及第 1 和 3 列。 这样可以修改矩阵,不需要常规切片。 |
a(3:2:21,:) |
a[2:21:2,:] |
每隔一行的a,从第三行开始到第二十一行 |
a(1:2:end,:) |
a[::2, :] |
a 的每隔一行,从第一行开始 |
a(end:-1:1,:) 或 flipud(a) |
a[::-1,:] |
行以相反顺序的a |
a([1:end 1],:) |
a[np.r_[:len(a),0]] |
在末尾附加第一行后的a |
a.' |
a.transpose() 或 a.T |
a 的转置 |
a' |
a.conj().transpose() 或 a.conj().T |
a 的共轭转置 |
a * b |
a @ b |
矩阵相乘 |
a .* b |
a * b |
逐元素相乘 |
a./b |
a/b |
逐元素除法 |
a.³ |
a**3 |
逐元素指数运算 |
(a > 0.5) |
(a > 0.5) |
其 i,j 元素为(a_ij > 0.5)的矩阵。MATLAB 结果是由逻辑值 0 和 1 组成的数组。NumPy 结果是由布尔值False和True组成的数组。 |
find(a > 0.5) |
np.nonzero(a > 0.5) |
寻找(a > 0.5)的索引 |
a(:,find(v > 0.5)) |
a[:,np.nonzero(v > 0.5)[0]] |
提取向量 v 中大于 0.5 的列的a |
a(:,find(v>0.5)) |
a[:, v.T > 0.5] |
提取向量 v 中大于 0.5 的列的a |
a(a<0.5)=0 |
a[a < 0.5]=0 |
a 中小于 0.5 的元素归零 |
a .* (a>0.5) |
a * (a > 0.5) |
a 中小于 0.5 的元素归零 |
a(:) = 3 |
a[:] = 3 |
将所有值设置为相同的标量值 |
y=x |
y = x.copy() |
NumPy 通过引用赋值 |
y=x(2,:) |
y = x[1, :].copy() |
NumPy 的切片是通过引用进行的 |
y=x(:) |
y = x.flatten() |
将数组转换为向量(请注意,这会强制进行复制)。要获得与 MATLAB 中的数据顺序相同的数据顺序,请使用x.flatten('F')。 |
1:10 |
np.arange(1., 11.) 或 np.r_[1.:11.] 或 np.r_[1:10:10j] |
创建一个递增向量(见注 RANGES) |
0:9 |
np.arange(10.) 或 np.r_[:10.] 或 np.r_[:9:10j] |
创建一个递增向量(见注 RANGES) |
[1:10]' |
np.arange(1.,11.)[:, np.newaxis] |
创建一个列向量 |
zeros(3,4) |
np.zeros((3, 4)) |
64 位浮点零值填充的 3x4 二维数组 |
zeros(3,4,5) |
np.zeros((3, 4, 5)) |
64 位浮点零值填充的 3x4x5 三维数组 |
ones(3,4) |
np.ones((3, 4)) |
64 位浮点 1 值填充的 3x4 二维数组 |
eye(3) |
np.eye(3) |
3x3 单位矩阵 |
diag(a) |
np.diag(a) |
返回 2D 数组a的对角线元素的向量 |
diag(v,0) |
np.diag(v, 0) |
返回一个非零值为向量v元素的方形对角矩阵 |
|
rng(42,'twister')
rand(3,4)
|
from numpy.random import default_rng
rng = default_rng(42)
rng.random(3, 4)
or older version: random.rand((3, 4)) | 用默认的随机数生成器和种子 = 42 生成一个随机的 3x4 数组 |
linspace(1,3,4) |
np.linspace(1,3,4) |
在 1 和 3 之间等间隔取 4 个样本,包括 1 和 3 |
|---|---|---|
[x,y]=meshgrid(0:8,0:5) |
np.mgrid[0:9.,0:6.] 或 np.meshgrid(r_[0:9.],r_[0:6.]) |
两个二维数组:一个是 x 值,另一个是 y 值 |
ogrid[0:9.,0:6.] 或 np.ix_(np.r_[0:9.],np.r_[0:6.] |
在网格上评估函数的最佳方法 | |
[x,y]=meshgrid([1,2,4],[2,4,5]) |
np.meshgrid([1,2,4],[2,4,5]) |
两个二维数组:一个是 x 值,另一个是 y 值 |
np.ix_([1,2,4],[2,4,5]) |
在网格上评估函数的最佳方法 | |
repmat(a, m, n) |
np.tile(a, (m, n)) |
创建 a 的 m 行 n 列的副本 |
[a b] |
np.concatenate((a,b),1) 或 np.hstack((a,b)) 或 np.column_stack((a,b)) 或 np.c_[a,b] |
拼接 a 和 b 的列 |
[a; b] |
np.concatenate((a,b)) 或 np.vstack((a,b)) 或 np.r_[a,b] |
拼接 a 和 b 的行 |
max(max(a)) |
a.max() 或 np.nanmax(a) |
a 的最大元素(对于 MATLAB 的 ndims(a)<=2,如果存在 NaN,则 nanmax 将忽略这些值并返回最大值) |
max(a) |
a.max(0) |
数组 a 每列的最大元素 |
max(a,[],2) |
a.max(1) |
数组 a 每行的最大元素 |
max(a,b) |
np.maximum(a, b) |
逐元素比较 a 和 b ,返回每对中最大的值 |
norm(v) |
np.sqrt(v @ v) 或 np.linalg.norm(v) |
向量 v 的 L2 范数 |
a & b |
logical_and(a,b) |
逐元素 AND 运算符(NumPy ufunc)参见注释 LOGICOPS |
a | b |
np.logical_or(a,b) |
逐元素 OR 运算符(NumPy ufunc)参见注释 LOGICOPS |
bitand(a,b) |
a & b |
按位 AND 运算符(Python 原生和 NumPy ufunc) |
bitor(a,b) |
a | b |
按位 OR 运���符(Python 原生和 NumPy ufunc) |
inv(a) |
linalg.inv(a) |
方阵 a 的逆 |
pinv(a) |
linalg.pinv(a) |
二维数组 a 的伪逆 |
rank(a) |
np.linalg.matrix_rank(a) |
二维数组 a 的秩 |
a\b |
如果 a 是方阵,则为 linalg.solve(a, b);否则为 linalg.lstsq(a, b) |
解方程 a x = b 的解 x |
b/a |
解方程 a.T x.T = b.T |
解方程 x a = b 的解 x |
[U,S,V]=svd(a) |
U, S, Vh = linalg.svd(a); V = Vh.T |
二维数组 a 的奇异值分解 |
chol(a) |
linalg.cholesky(a) |
二维数组 a 的 Cholesky 分解 |
[V,D]=eig(a) |
D,V = linalg.eig(a) |
a 的特征值 (\lambda) 和特征向量 (v) ,满足 (\mathbf{a} v = \lambda v) |
[V,D]=eig(a,b) |
D,V = linalg.eig(a, b) |
a,b 的特征值 (\lambda) 和特征向量 (v) ,满足 (\mathbf{a} v = \lambda \mathbf{b} v) |
[V,D]=eigs(a,3) |
D,V = eigs(a, k=3) |
找到二维数组 a 中最大的 k=3 个特征值和特征向量 |
[Q,R]=qr(a,0) |
Q,R = linalg.qr(a) |
QR 分解 |
[L,U,P]=lu(a),其中 a==P'*L*U |
P,L,U = linalg.lu(a),其中 a == P@L@U |
带部分主元的 LU 分解(注意:P(MATLAB)==传置(P(NumPy))) |
conjgrad |
cg |
共轭梯度解算器 |
fft(a) |
np.fft.fft(a) |
a 的傅里叶变换 |
ifft(a) |
np.fft.ifft(a) |
a的傅立叶反变换 |
sort(a) |
np.sort(a)或a.sort(axis=0) |
排序 2D 数组a的每一列 |
sort(a, 2) |
np.sort(a, axis=1)或a.sort(axis=1) |
对 2D 数组a的每一行进行排序 |
[b,I]=sortrows(a,1) |
I = np.argsort(a[:, 0]); b = a[I, :] |
将数组a按第一列排序,并保存为数组b |
x = Z\y |
x = linalg.lstsq(Z, y) |
执行形式为(\mathbf{Zx}=\mathbf{y})的线性回归 |
decimate(x, q) |
signal.resample(x, np.ceil(len(x)/q)) |
通过低通滤波进行下采样 |
unique(a) |
np.unique(a) |
数组a中唯一值的向量 |
squeeze(a) |
a.squeeze() |
移除数组a的单例维度。注意,MATLAB 将始终返回 2D 或更高维数组,而 NumPy 将返回 0D 或更高维数组 |
通用等价物
| MATLAB | NumPy | 注释 |
|---|---|---|
help func |
info(func)或help(func)或func?(在 IPython 中) |
获取函数func的帮助信息 |
which func |
见注意事项 HELP | 查找func的定义位置 |
type func |
np.source(func)或func??(在 IPython 中) |
打印func的源代码(如果不是原生函数) |
% comment |
# comment |
使用文本comment对代码行进行注释 |
|
for i=1:3
fprintf('%i\n',i)
end
|
for i in range(1, 4):
print(i)
使用 for 循环打印数字 1, 2 和 3,使用[range](https://docs.python.org/3/library/stdtypes. html#range "(在 Python v3.11 中)") |
|---|
a && b |
a || b |
|
>> 4 == 4
ans = 1
>> 4 == 5
ans = 0
|
>>> 4 == 4
True
>>> 4 == 5
False
在 Python 中,布尔对象是True和False,而不是 MATLAB 的逻辑类型1和0。 |
|---|
|
a=4
if a==4
fprintf('a = 4\n')
elseif a==5
fprintf('a = 5\n')
end
|
a = 4
if a == 4:
print('a = 4')
elif a == 5:
print('a = 5')
创建一个 if-else 语句以检查a是否为 4 或 5,并打印结果 |
|---|
1*i、1*j、1i、1j |
eps |
load data.mat |
ode45 |
ode15s |
同等的线性代数
| MATLAB | NumPy | 注释 |
|---|---|---|
ndims(a) |
np.ndim(a) or a.ndim |
数组 a 的维度数 |
numel(a) |
np.size(a) or a.size |
数组 a 的元素个数 |
size(a) |
np.shape(a) or a.shape |
数组 a 的尺寸 |
size(a,n) |
a.shape[n-1] |
获取数组 a 的第 n 维度的元素个数。(注意 MATLAB 使用基于 1 的索引,而 Python 使用基于 0 的索引,参见注释 INDEXING) |
[ 1 2 3; 4 5 6 ] |
np.array([[1., 2., 3.], [4., 5., 6.]]) |
定义一个 2x3 的 2D 数组 |
[ a b; c d ] |
np.block([[a, b], [c, d]]) |
从块 a、b、c 和 d 构造矩阵 |
a(end) |
a[-1] |
访问 MATLAB 向量(1xn 或 nx1)或长度为 n 的 1D NumPy 数组 a 中的最后一个元素 |
a(2,5) |
a[1, 4] |
访问 2D 数组 a 中第二行第五列的元素 |
a(2,:) |
a[1] or a[1, :] |
2D 数组 a 的第二行 |
a(1:5,:) |
a[0:5] or a[:5] or a[0:5, :] |
2D 数组 a 的前 5 行 |
a(end-4:end,:) |
a[-5:] |
2D 数组 a 的最后 5 行 |
a(1:3,5:9) |
a[0:3, 4:9] |
2D 数组 a 的第一到第三行和第五到第九列 |
a([2,4,5],[1,3]) |
a[np.ix_([1, 3, 4], [0, 2])] |
第 2、4 和 5 行以及第 1 和 3 列。这允许修改矩阵,并且不需要常规切片。 |
a(3:2:21,:) |
a[2:21:2,:] |
从第三行开始,每隔一行的 a,直到第二十一行 |
a(1:2:end,:) |
a[::2, :] |
a 的每隔一行,从第一行开始 |
a(end:-1:1,:) or flipud(a) |
a[::-1,:] |
行顺序相��的 a |
a([1:end 1],:) |
a[np.r_[:len(a),0]] |
a 的副本,附加了第一行的副本到末尾 |
a.' |
a.transpose() or a.T |
a 的转置 |
a' |
a.conj().transpose() or a.conj().T |
a 的共轭转置 |
a * b |
a @ b |
矩阵相乘 |
a .* b |
a * b |
逐元素相乘 |
a./b |
a/b |
逐元素相除 |
a.³ |
a**3 |
逐元素求幂 |
(a > 0.5) |
(a > 0.5) |
矩阵,其第 i、j 个元素为 (a_ij > 0.5)。MATLAB 结果是一个由 0 和 1 组成的逻辑值数组。NumPy 结果是一个由布尔值 False 和 True 组成的数组。 |
find(a > 0.5) |
np.nonzero(a > 0.5) |
找到满足 (a > 0.5) 的索引 |
a(:,find(v > 0.5)) |
a[:,np.nonzero(v > 0.5)[0]] |
提取矩阵 a 中向量 v > 0.5 的列 |
a(:,find(v>0.5)) |
a[:, v.T > 0.5] |
提取矩阵 a 中列向量 v > 0.5 的列 |
a(a<0.5)=0 |
a[a < 0.5]=0 |
小于 0.5 的 a 元素变为零 |
a .* (a>0.5) |
a * (a > 0.5) |
小于 0.5 的 a 元素变为零 |
a(:) = 3 |
a[:] = 3 |
将所有值设置为相同的标量值 |
y=x |
y = x.copy() |
NumPy 通过引用赋值 |
y=x(2,:) |
y = x[1, :].copy() |
NumPy 的切片是通过引用进行的 |
y=x(:) |
y = x.flatten() |
将数组转换成向量(请注意,这会强制执行复制)。为了获得与 MATLAB 中相同的数据排序,使用 x.flatten('F')。 |
1:10 |
np.arange(1., 11.) or np.r_[1.:11.] or np.r_[1:10:10j] |
创建一个递增的向量(参见 范围注释(RANGES)) |
0:9 |
np.arange(10.) or np.r_[:10.] or np.r_[:9:10j] |
创建一个递增的向量(参见 范围注释(RANGES)) |
[1:10]' |
np.arange(1.,11.)[:, np.newaxis] |
创建一个列向量 |
zeros(3,4) |
np.zeros((3, 4)) |
全部为 0 的 3x4 二维数组,64 位浮点类型 |
zeros(3,4,5) |
np.zeros((3, 4, 5)) |
全部为 0 的 3x4x5 三维数组,64 位浮点类型 |
ones(3,4) |
np.ones((3, 4)) |
全部为 1 的 3x4 二维数组,64 位浮点类型 |
eye(3) |
np.eye(3) |
3x3 单位矩阵 |
diag(a) |
np.diag(a) |
返回二维数组 a 对角线上的元素构成的向量 |
diag(v,0) |
np.diag(v, 0) |
返回一个正方形对角矩阵,其非零值为向量 v 的元素 |
|
rng(42,'twister')
rand(3,4)
|
from numpy.random import default_rng
rng = default_rng(42)
rng.random(3, 4)
或者旧版本:random.rand((3, 4)) | 使用默认的随机数生成器和 seed = 42 生成一个随机的 3x4 数组 |
linspace(1,3,4) |
np.linspace(1,3,4) |
在 1 到 3 之间生成 4 个等差样本,包括边界值 |
|---|---|---|
[x,y]=meshgrid(0:8,0:5) |
np.mgrid[0:9.,0:6.] or np.meshgrid(r_[0:9.],r_[0:6.]) |
两个 2D 数组:一个是 x 值,另一个是 y 值 |
ogrid[0:9.,0:6.] or np.ix_(np.r_[0:9.],np.r_[0:6.] |
在网格上计算函数的最佳方法 | |
[x,y]=meshgrid([1,2,4],[2,4,5]) |
np.meshgrid([1,2,4],[2,4,5]) |
|
np.ix_([1,2,4],[2,4,5]) |
在网格上计算函数的最佳方法 | |
repmat(a, m, n) |
np.tile(a, (m, n)) |
创建大小为 m × n 的 a 的副本 |
[a b] |
np.concatenate((a,b),1) or np.hstack((a,b)) or np.column_stack((a,b)) or np.c_[a,b] |
连接数组 a 和 b 的列 |
[a; b] |
np.concatenate((a,b)) or np.vstack((a,b)) or np.r_[a,b] |
连接数组 a 和 b 的行 |
max(max(a)) |
a.max() or np.nanmax(a) |
a 的最大值(对于 MATLAB,ndims(a)<=2,如果存在 NaN,则 nanmax 会忽略这些 NaN 并返回最大值) |
max(a) |
a.max(0) |
数组 a 每列的最大值 |
max(a,[],2) |
a.max(1) |
数组 a 每行的最大值 |
max(a,b) |
np.maximum(a, b) |
比较 a 和 b 的元素并��个返回最大值 |
norm(v) |
np.sqrt(v @ v) or np.linalg.norm(v) |
向量 v 的 L2 范数 |
a & b |
logical_and(a,b) |
元素逐个进行与运算(NumPy ufunc)查看逻辑操作注释(LOGICOPS) |
a | b |
np.logical_or(a,b) |
元素逐个进行或运算(NumPy ufunc)查看逻辑操作注释(LOGICOPS) |
bitand(a,b) |
a & b |
按位与运算符(Python 原生和 NumPy ufunc) |
bitor(a,b) |
a | b |
按位或运算符(Python 本地和 NumPy ufunc) |
inv(a) |
linalg.inv(a) |
2D 数组a的逆 |
pinv(a) |
linalg.pinv(a) |
2D 数组a的伪逆 |
rank(a) |
np.linalg.matrix_rank(a) |
2D 数组a的矩阵秩 |
a\b |
若a是方阵使用linalg.solve(a, b);否则使用linalg.lstsq(a, b) |
解线性方程组a x = b得到的解 x |
b/a |
解a.T x.T = b.T |
解方程x a = b得到的解 x |
[U,S,V]=svd(a) |
U, S, Vh = linalg.svd(a); V = Vh.T |
a的奇异值分解 |
chol(a) |
linalg.cholesky(a) |
2D 数组a的 Cholesky 分解 |
[V,D]=eig(a) |
D,V = linalg.eig(a) |
a的特征值(\lambda)和特征向量(v),其中(\mathbf{a} v = \lambda v) |
[V,D]=eig(a,b) |
D,V = linalg.eig(a, b) |
a和b的特征值(\lambda)和特征向量(v),其中(\mathbf{a} v = \lambda \mathbf{b} v) |
[V,D]=eigs(a,3) |
D,V = eigs(a, k=3) |
找到 2D 数组a的前k=3个最大特征值和特征向量 |
[Q,R]=qr(a,0) |
Q,R = linalg.qr(a) |
QR 分解 |
[L,U,P]=lu(a),其中a==P'*L*U |
P,L,U = linalg.lu(a),其中a == P@L@U |
具有部分主元的 LU 分解(注意:P(MATLAB)==转置 P(NumPy)) |
conjgrad |
cg |
共轭梯度解算器 |
fft(a) |
np.fft.fft(a) |
a的傅里叶变换 |
ifft(a) |
np.fft.ifft(a) |
a的傅里叶逆变换 |
sort(a) |
np.sort(a)或a.sort(axis=0) |
对 2D 数组a的每一列排序 |
sort(a, 2) |
np.sort(a, axis=1)或a.sort(axis=1) |
对 2D 数组a的每一行排序 |
[b,I]=sortrows(a,1) |
I = np.argsort(a[:, 0]); b = a[I,:] |
将数组a按第一列排序后保存为数组b |
x = Z\y |
x = linalg.lstsq(Z, y) |
执行形式为(\mathbf{Zx}=\mathbf{y})的线性回归 |
decimate(x, q) |
signal.resample(x, np.ceil(len(x)/q)) |
通过低通滤波下采样 |
unique(a) |
np.unique(a) |
数组a中的唯一值向量 |
squeeze(a) |
a.squeeze() |
移除数组a的单例维度。请注意,MATLAB 始终返回 2D 或更高阶数组,而 NumPy 将返回 0D 或更高阶数组 |
注释
子矩阵: 可以使用ix_命令和索引列表对子矩阵进行赋值。例如,对于 2D 数组a,可以这样操作:ind=[1, 3]; a[np.ix_(ind, ind)] += 100。
帮助: Python 没有直接相当于 MATLAB 中which命令的命令,但help和numpy.source命令通常会列出函数所在的文件名。Python 还有一个inspect模块(导入import inspect),其中提供了一个getfile函数通常也会起作用。
索引:MATLAB 使用基于一的索引,因此序列的初始元素索引为 1。Python 使用基于零的索引,因此序列的初始元素索引为 0。关于这一点可能会产生混淆和激烈争论,因为每种方式都有其优势和劣势。基于一的索引符合通常的人类语言使用习惯,其中序列的“第一个”元素索引为 1。基于零的索引简化了索引操作。也请参见 Edsger W. Dijkstra 教授的一篇文章。
范围:在 MATLAB 中,0:5既可以用作范围字面量,也可以用作‘切片’索引(放在括号内);然而在 Python 中,像0:5这样的构造只能作为切片索引(放在方括号内)使用。因此,为了使 NumPy 可以拥有类似简洁的范围构造机制,特别创建了r_对象。需要注意的是,r_ 不像函数或构造函数一样被调用,而是使用方括号进行索引,这样可以在参数中使用 Python 的切片语法。
逻辑操作:在 NumPy 中,& 和 | 是按位与/或运算,而在 MATLAB 中,& 和 | 分别是逻辑与/或运算。这两者看起来可能是一样的,但实际上存在重要的区别。如果你曾经使用过 MATLAB 的 & 或 | 运算符,那么在 NumPy 中应该使用对应的 ufuncs logical_and/logical_or。MATLAB 和 NumPy 的 & 和 | 操作符之间的显著区别包括:
-
非逻辑 {0,1} 输入:NumPy 的输出是输入的按位与。MATLAB 将任何非零值视为 1,并返回逻辑与。例如在 NumPy 中
(3 & 4)的结果是0,而在 MATLAB 中3和4都被视为逻辑 true,因此(3 & 4)的结果是1。 -
优先级:NumPy 的
&运算符的优先级高于诸如<和>的逻辑运算符;而 MATLAB 则相反。
如果你知道参数是布尔值,你可以使用 NumPy 的按位运算符,但是在使用括号时要小心,就像这样:z = (x > 1) & (x < 2)。NumPy 没有形式上的 logical_and 和 logical_or 运算符是 Python 设计的一个不幸的结果。
重塑和线性索引: MATLAB 始终允许使用标量或线性索引访问多维数组,而 NumPy 则不是。线性索引在 MATLAB 程序中很常见,例如,对矩阵进行find()返回它们,而 NumPy 的find()行为有所不同。在转换 MATLAB 代码时,可能需要首先将矩阵重塑为线性序列,执行一些索引操作,然后再进行重塑。由于 reshape(通常)提供对相同存储的视图,因此应该可以相当高效地完成此操作。请注意,NumPy 中 reshape 的扫描顺序默认为‘C’顺序,而 MATLAB 使用 Fortran 顺序。如果你仅仅是将其转换为线性序列然后再转换回来,这并不重要。但如果你正在从依赖扫描顺序的 MATLAB 代码转换 reshape,那么此 MATLAB 代码:z = reshape(x,3,4);应该在 NumPy 中变为z = x.reshape(3,4,order='F').copy()。
‘array’或‘matrix’?我应该使用哪个?
从历史上看,NumPy 提供了一种特殊的矩阵类型,np.matrix,它是 ndarray 的一个子类,使二进制操作变成线性代数操作。你可能会在一些现有代码中看到它,而不是np.array。那么,应该使用哪一个?
简短答案
使用 arrays。
-
它们支持 MATLAB 中支持的多维数组代数运算
-
它们是 NumPy 的标准向量/矩阵/张量类型。许多 NumPy 函数返回数组,而不是矩阵。
-
元素操作与线性代数操作有明显区别。
-
如果你喜欢,可以使用标准向量或行/列向量。
直到 Python 3.5,使用array类型的唯一缺点是你必须使用dot而不是*来乘法(缩减)两个张量(数量积,矩阵向量乘法等)。从 Python 3.5 开始,你可以使用矩阵乘法@运算符。
鉴于上述,我们计划最终弃用matrix。
长答案
NumPy 包含array类和matrix类。array类旨在成为通用的多维数组,用于各种数值计算,而matrix旨在特定地促进线性代数计算。在实践中,这两者之间只有少数几个关键差异。
-
运算符
*和@,函数dot()和multiply():-
对于
array,*表示逐元素相乘,而@表示矩阵乘法;它们有相关的函数multiply()和dot()。(Python 3.5 之前,@不存在,人们必须使用dot()进行矩阵乘法)。 -
对于
matrix,*表示矩阵乘法,对于逐元素乘法,人们必须使用multiply()函数。
-
-
向量(一维数组)的处理
-
对于
array来说,向量形状 1xN,Nx1 和 N 是完全不同的事情。像A[:,1]这样的操作返回形状为 N 的一维数组,而不是形状为 Nx1 的二维数组。在一维array上进行转置没有任何效果。 -
对于
matrix,一维数组总是转换为 1xN 或 Nx1 矩阵(行向量或列向量)。A[:,1]返回形状为 Nx1 的二维矩阵。
-
-
处理更高维数组(ndim > 2)
-
array对象可以具有大于 2 的维数; -
matrix对象始终具有确切的两个维度。
-
-
便利属性
-
array具有.T 属性,返回数据的转置。 -
matrix还具有.H, .I 和 .A 属性,分别返回矩阵的共轭转置、逆和asarray()。
-
-
便利构造函数
-
array构造函数接受(嵌套的)Python 序列作为初始化器。如array([[1,2,3],[4,5,6]])。 -
matrix构造函数另外接受方便的字符串初始化器。如matrix("[1 2 3; 4 5 6]").
-
使用两者都有利弊:
-
array-
:)逐元素乘法很容易:A*B。 -
:(您必须记住,矩阵乘法有自己的运算符@。 -
:)您可以将一维数组视为行向量或列向量。A @ v将v视为列向量,而v @ A将v视为行向量。这样可以避免您输入许多转置。 -
:)array是 NumPy 的“默认”类型,因此它得到了最多的测试,并且最有可能被使用 NumPy 的第三方代码返回。 -
:)它在处理任意维度的数据时非常方便。 -
:)如果您熟悉张量代数的话,语义上更接近。 -
:)所有操作(*,/,+,-等)都是逐元素的。 -
:(scipy.sparse 中的稀疏矩阵与数组的交互不太好。
-
-
matrix-
:\\行为更像 MATLAB 矩阵。 -
<:(三维数据需要使用array,或者可能是matrix的 Python 列表。 -
<:(两维矩阵的最小值。不能有向量。它们必须被转换为单列或单行矩阵。 -
<:(由于在 NumPy 中array是默认的,一些函数可能返回array,即使您给它们一个matrix作为参数。这不应该发生在 NumPy 函数中(如果发生了,那是个错误),但基于 NumPy 的第三方代码可能不像 NumPy 那样尊重类型保留。 -
:)A*B是矩阵乘法,所以它看起来就像您在线性代数中写的(对于 Python >= 3.5,普通数组使用@运算符也有同样的便利)。 -
<:(逐元素乘法需要调用一个函数,multiply(A,B)。 -
<:(使用运算符重载有点不合逻辑:*不逐元素工作,但/却是。 -
与
scipy.sparse的交互更清晰。
-
因此,更建议使用array。实际上,我们最终打算停用matrix。
简短答案
使用数组。
-
支持在 MATLAB 中支持的多维数组代数
-
它们是 NumPy 的标准向量/矩阵/张量类型。许多 NumPy 函数返回数组,而不是矩阵。
-
元素级操作和线性代数操作之间有明显的区别。
-
如果需要,你可以使用标准向量或行向量/列向量。
在 Python 3.5 之前,使用 array 类型的唯一不利之处是必须使用 dot 而不是 * 进行乘法(缩减)两个张量(标量积、矩阵向量乘法等)。自从 Python 3.5 以来,可以使用矩阵乘法 @ 运算符。
根据上面的内容,我们打算最终废弃 matrix。
较长的回答
NumPy 中包含 array 类和 matrix 类。array 类旨在成为一种通用的 n 维数组,适用于各种数值计算,而 matrix 则旨在专门用于线性代数计算。实际上,这两者之间只有一小部分关键差异。
-
运算符
*和@,函数dot()和multiply():-
对于
array,*表示逐元素乘法,而@表示矩阵乘法;它们分别对应的函数是multiply()和dot()。(在 Python 3.5 之前,@不存在,必须使用dot()进行矩阵乘法)。 -
对于
matrix,*表示矩阵乘法,对于逐元素乘法必须使用multiply()函数。
-
-
向量(一维数组)的处理
-
对于
array,向量的形状 1xN、Nx1 和 N 是不同的概念。例如,A[:,1]返回形状为 N 的一维数组,而不是形状为 Nx1 的二维数组。对一维array进行转置没有任何变化。 -
对于
matrix,一维数组总是被转换为 1xN 或 Nx1 的矩阵(行向量或列向量)。A[:,1]返回形状为 Nx1 的二维矩阵。
-
-
高维数组(ndim > 2)的处理
-
array对象可以具有大于 2 的维数; -
matrix对象始终仅有两个维度。
-
-
方便的属性
-
array具有.T属性,可以返回数据的转置。 -
matrix还有.H、.I和.A属性,它们分别返回矩阵的共轭转置、逆和asarray()。
-
-
方便的构造函数
-
array构造函数接受嵌套的 Python 序列作为初始化参数。例如,array([[1,2,3],[4,5,6]])。 -
matrix构造函数还支持方便的字符串初始化。例如,matrix("[1 2 3; 4 5 6]")。
-
使用它们都有利有弊:
-
array-
:)逐元素乘法很简单:A*B。 -
:(你必须记住矩阵乘法有自己的运算符@。 -
:)你可以将一维数组当作行向量或列向量处理。A @ v将v视为列向量,而v @ A将v视为行向量。这样可以减少输入转置的次数。 -
:)array是“默认”的 NumPy 类型,因此它受到最多的测试,并且是第三方使用 NumPy 的代码可能返回的类型。 -
:)在处理任意维数的数据时都非常便捷。 -
:)与张量代数更接近的语义,如果你熟悉的话。 -
:)所有操作(*、/、+、-等)都是逐个元素进行的。 -
:(使用scipy.sparse的稀疏矩阵与数组的交互效果不太好。
-
-
矩阵
-
:\\行为更像 MATLAB 矩阵。 -
<:(二维矩阵的最大值。要保存三维数据,你需要使用array或者可能是一个matrix的 Python 列表。 -
<:(二维矩阵的最小值。你不能有向量。它们必须被转换为单列矩阵或单行矩阵。 -
<:(由于array是 NumPy 的默认选项,所以一些函数可能会返回一个array,即使你将matrix作为参数传递给它们也会如此。 NumPy 函数不应该出现这种情况(如果出现了就是一个 bug),但基于 NumPy 的第三方代码可能不像 NumPy 那样保留类型信息。 -
:)A*B是矩阵乘法,因此它的写法与线性代数中一样(对于 Python >= 3.5,普通数组可以使用@操作符达到相同的方便性)。 -
<:(对元素进行逐个乘法操作需要调用函数multiply(A, B)。 -
<:(操作符重载的使用有点不合逻辑:*不对元素进行操作,但/是对每个元素进行操作的。 -
与
scipy.sparse的交互更清晰。
-
因此,更建议使用 array。事实上,我们打算最终废弃 matrix。
定制环境
在 MATLAB 中,定制环境的主要工具是修改搜索路径以包含你喜欢的函数的位置。你可以将这样的定制放入 MATLAB 在启动时运行的启动脚本中。
NumPy,或者更准确地说是 Python,有类似的功能。
-
若要修改 Python 搜索路径以包含自己模块的位置,请定义
PYTHONPATH环境变量。 -
当启动交互式 Python 解释器时,若要执行特定的脚本文件,请定义
PYTHONSTARTUP环境变量,其包含你启动脚本的名称。
与 MATLAB 不同,你需要先使用 'import' 语句使特定文件中的函数可访问,然后才能立即调用。
例如,你可以创建一个启动脚本,内容如下(注意:此处仅为示例,并不是“最佳实践”的陈述):
# Make all numpy available via shorter 'np' prefix
import numpy as np
#
# Make the SciPy linear algebra functions available as linalg.func()
# e.g. linalg.lu, linalg.eig (for general l*B@u==A@u solution)
from scipy import linalg
#
# Define a Hermitian function
def hermitian(A, **kwargs):
return np.conj(A,**kwargs).T
# Make a shortcut for hermitian:
# hermitian(A) --> H(A)
H = hermitian
要使用已弃用的 matrix 和其他 matlib 函数:
# Make all matlib functions accessible at the top level via M.func()
import numpy.matlib as M
# Make some matlib functions accessible directly at the top level via, e.g. rand(3,3)
from numpy.matlib import matrix,rand,zeros,ones,empty,eye
链接
在 mathesaurus.sf.net/ 可以找到另一个相对陈旧的 MATLAB/NumPy 相关信息。
可以在 主题软件页面 中找到用于使用 Python 进行科学工作的工具的详尽列表。
请查看 Python 软件列表:脚本语言 获取使用 Python 作为脚本语言的软件列表。
MATLAB® 和 SimuLink® 是 The MathWorks, Inc. 的注册商标。
NumPy 特性
一系列与内置 NumPy 功能相关的笔记。
-
n 维数组上的线性代数
-
保存和分享您的 NumPy 数组
-
掩码数组
NumPy 如何操作
这些文档旨在提供使用 NumPy 执行常见任务的方法。有关包中包含的函数和类的详细参考文档,请参见 API 参考。
-
如何编写 NumPy 操作指南
-
读取和写入文件
-
如何索引
ndarrays -
验证 NumPy 中的错误和 bug 修复
-
如何创建具有等距数值的数组
高级用法和互操作性
从源码编译
在本地计算机上构建可以完全控制构建选项。如果你是一名熟悉使用命令行的 MacOS 或 Linux 用户,则可以继续按照下面的说明构建 NumPy。
注意
如果要构建用于开发目的的 NumPy,请参阅 Setting up and using your development environment 获取更多信息。
先决条件
编译 NumPy 需要已安装以下软件:
-
Python 3.9.x 或更高版本
请注意,还需要安装 Python 开发头文件,例如,在 Debian/Ubuntu 上需要同时安装 python3 和 python3-dev。在 Windows 和 macOS 上通常不会出现此问题。
-
编译器
NumPy 的很大一部分是用 C 和 C++ 编写的。你需要一个符合 C99 标准的 C 编译器,以及一个符合 C++17 标准的 C++ 编译器。
尽管构建 NumPy 不需要 FORTRAN 77 编译器,在运行
numpy.f2py测试时需要它。如果未自动检测到编译器,则会跳过这些测试。注意,NumPy 主要是使用 GNU 编译器进行开发,并在 MSVC 和 Clang 编译器上进行测试。像 Intel、Absoft、Sun、NAG、Compaq、Vast、Portland、Lahey、HP、IBM 等其他供应商的编译器仅以社区反馈的形式提供支持,并不保证可以直接使用。推荐使用 GCC 6.5(或更高版本)编译器。在 ARM64(aarch64)上推荐使用 GCC 8.x(或更高版本)。
-
线性代数库
NumPy 不需要安装任何外部线性代数库。然而,如果这些库可用,NumPy 的设置脚本可以检测到并用于构建。可以使用多种不同的 LAPACK 库设置,包括优化的 LAPACK 库,如 OpenBLAS 或 MKL。这些库的选择和位置以及包含路径和其他构建选项可以在
.pc文件中指定,如 BLAS 和 LAPACK 中所述。 -
Cython
构建 NumPy 需要一个较新版本的 Cython。
-
NumPy 源代码
按照 Contributing to NumPy 中的说明,克隆仓库。
注意
从版本 1.26 开始,NumPy 将采用 Meson 作为构建系统(详见 Status of numpy.distutils and migration advice 和 Understanding Meson)。
基本安装
要从本地源代码构建和安装 NumPy,请运行:
pip install .
这将安装所有构建依赖项,并使用 Meson 编译和安装 NumPy 的 C 扩展和 Python 模块。如果需要对构建选项和命令有更多控制,请参阅以下各节。
要执行可以从源文件夹运行的就地构建,请运行:
pip install -r build_requirements.txt
pip install -e . --no-build-isolation
注意:有关在 NumPy 本身上进行开发工作的构建说明,请参阅 设置和使用开发环境。
使用 Meson 进行高级构建
Meson 支持标准环境变量CC,CXX和FC来选择特定的 C、C++和/或 Fortran 编译器。这些环境变量在Meson 文档中的参考表中有文档说明。
请注意,环境变量仅在干净构建时应用,因为它们影响配置阶段(即 meson setup)。增量重建不会对环境变量的更改做出反应-您必须运行git clean -xdf并进行完全重建,或运行meson setup --reconfigure。
更多选项,包括选择编译器、设置自定义编译器标志和控制并行性,请参阅编译器选择和自定义构建(来自 SciPy 文档)和Meson FAQ。
测试
确保测试你的构建。为了确保一切都正常,查看所有测试是否通过。
测试套件需要额外的依赖项,可以通过以下方式轻松安装:
python -m pip install -r test_requirements.txt
运行完整的测试套件:
cd .. # avoid picking up the source tree
pytest --pyargs numpy
有关测试的详细信息,请参阅测试构建。
加速 BLAS/LAPACK 库
NumPy 搜索优化的线性代数库,例如 BLAS 和 LAPACK。搜索这些库有特定的顺序,如下所述和meson_options.txt文件中描述。
交叉编译
对于交叉编译指令,请参阅交叉编译和 Meson 文档。
先决条件
构建 NumPy 需要安装以下软件:
-
Python 3.9.x 或更新版本
请注意,还需要安装 Python 开发头文件,例如,在 Debian/Ubuntu 上需要同时安装python3和python3-dev。在 Windows 和 macOS 上,这通常不是问题。
-
编译器
NumPy 的大部分代码是用 C 和 C++编写的。您需要一个符合 C99 标准的 C 编译器,以及一个符合 C++17 标准的 C++编译器。
虽然构建 NumPy 不需要 FORTRAN 77 编译器,但运行
numpy.f2py测试需要。如果编译器没有被自动检测到,则这些测试会被跳过。请注意,NumPy 主要是使用 GNU 编译器开发并在 MSVC 和 Clang 编译器上进行测试。来自其他供应商的编译器(如 Intel、Absoft、Sun、NAG、Compaq、Vast、Portland、Lahey、HP、IBM)仅通过社区反馈的形式支持,并且可能无法直接使用。推荐使用 GCC 6.5(及更高版本)编译器。在 ARM64(aarch64)上,推荐使用 GCC 8.x(及更高版本)。
-
线性代数库
NumPy 不需要安装任何外部线性代数库。但是,如果这些库可用,NumPy 的设置脚本可以检测到并用于构建。可以使用多种不同的 LAPACK 库设置,包括经过优化的 LAPACK 库,如 OpenBLAS 或 MKL。这些库的选择和位置以及包含路径等构建选项可以在
.pc文件中指定,如 BLAS 和 LAPACK 中所述。 -
Cython
要构建 NumPy,您需要一个较新版本的 Cython。
-
NumPy 源代码
按照 为 NumPy 做出贡献 中的说明克隆存储库。
注意
从版本 1.26 开始,NumPy 将采用 Meson 作为其构建系统(请参阅 numpy.distutils 的状态和迁移建议 和 理解 Meson 了解更多细节)。
基本安装
要从源代码的本地副本构建并安装 NumPy,请运行:
pip install .
这将安装所有构建依赖项并使用 Meson 编译并安装 NumPy 的 C 扩展和 Python 模块。如果您需要更多控制构建选项和命令,请参见以下章节。
要执行可以从源文件夹运行的原地构建,请运行:
pip install -r build_requirements.txt
pip install -e . --no-build-isolation
注意:有关在 NumPy 上进行开发工作的构建说明,请参阅 配置和使用开发环境。
使用 Meson 进行高级构建
Meson 支持标准环境变量 CC、CXX 和 FC 以选择特定的 C、C++ 和/或 Fortran 编译器。这些环境变量在 Meson 文档中的参考表中 有文档记录。
请注意,环境变量只会在干净构建时生效,因为它们会影响配置阶段(即,meson 设置)。增量重建不会对环境变量的更改做出反应-您必须运行 git clean -xdf 并进行完整重建,或运行 meson setup --reconfigure。
更多选项包括选择编译器、设置自定义编译器标志和控制并行性,请参阅编译器选择和自定义构建(来自 SciPy 文档)和the Meson FAQ。
使用 Meson 进行高级构建
Meson 支持标准环境变量CC、CXX和FC来选择特定的 C、C++和/或 Fortran 编译器。这些环境变量在Meson 文档中的参考表中有文档。
请注意,只有在干净的构建过程中,环境变量才会得到应用,因为它们影响配置阶段(即 meson setup)。增量重新构建不会对环境变量的更改作出反应-您必须运行git clean -xdf并进行全面重建,或者运行meson setup --reconfigure。
更多选项包括选择编译器、设置自定义编译器标志和控制并行性,请参阅编译器选择和自定义构建(来自 SciPy 文档)和the Meson FAQ。
测试
确保测试您的构建。为了确保一切正常,请检查所有测试是否通过。
测试套件需要额外的依赖项,可以通过以下命令轻松安装:
python -m pip install -r test_requirements.txt
运行完整的测试套件:
cd .. # avoid picking up the source tree
pytest --pyargs numpy
有关测试的详细信息,请参阅测试构建。
加速 BLAS/LAPACK 库
NumPy 搜索优化的线性代数库,如 BLAS 和 LAPACK。有特定的搜索这些库的顺序,如下所述和meson_options.txt文件中描述的。
交叉编译
如需交叉编译说明,请参阅交叉编译和 Meson 文档。
使用 NumPy C-API
-
如何扩展 NumPy
-
编写扩展模块
-
必需子程序
-
定义函数
-
无关键字参数的函数
-
带关键字参数的函数
-
引用计数
-
-
处理数组对象
-
转换任意序列对象
-
创建全新的 ndarray
-
访问 ndarray 内存和访问 ndarray 元素
-
-
示例
-
-
使用 Python 作为粘合剂
-
从 Python 调用其他编译库
-
手动生成的包装器
-
f2py
-
Cython
-
Cython 中的复数加法
-
Cython 中的图像滤波
-
结论
-
-
ctypes
-
拥有共享库
-
加载共享库
-
转换参数
-
调用函数
ndpointer
-
完整示例
-
结论
-
-
您可能会发现有用的其他工具
-
SWIG
-
SIP
-
Boost Python
-
PyFort
-
-
-
编写自己的 ufunc
-
创建新的通用函数
-
示例非通用函数扩展
-
带一种数据类型的 NumPy ufunc 示例
-
带有多种数据类型的 NumPy ufunc 示例
-
具有多个参数/返回值的示例 NumPy ufunc
-
具有结构化数组数据类型参数的示例 NumPy ufunc
-
-
超越基础知识
-
在数组中迭代元素
-
基本迭代
-
在除了一个轴之外的所有轴上进行迭代
-
在多个数组上进行迭代
-
在多个数组上进行广播
-
-
用户定义数据类型
-
添加新数据类型
-
注册强制类型转换函数
-
注册强制类型转换规则
-
注册 ufunc 循环
-
-
在 C 中对 ndarray 进行子类型化
-
创建子类型
-
ndarray 子类型的特定特征
-
array_finalize 方法
ndarray.__array_finalize__
-
array_priority 属性
ndarray.__array_priority__
-
array_wrap 方法
ndarray.__array_wrap__
-
-
-
F2PY 用户指南和参考手册
F2PY - Fortran 到 Python 接口生成器 - 实用程序的目的是提供 Python 与 Fortran 之间的连接。F2PY 是NumPy (numpy.f2py)的一部分,也作为一个独立的命令行工具可用。
F2PY 有助于创建/构建使其成为可能的 Python C/API 扩展模块
-
用于调用 Fortran 77/90/95 外部子例程以及 Fortran 90/95 模块子例程以及 C 函数;
-
用于访问 Fortran 77
COMMON块和 Fortran 90/95 模块数据,包括可分配数组
从 Python。
F2PY 可以作为命令行工具f2py或作为一个 Python 模块numpy.f2py来使用。虽然我们尝试将命令行工具作为 numpy 设置的一部分提供,但像 Windows 这样的某些平台很难可靠地将可执行文件放在PATH上。如果您的系统中没有f2py命令可用,您可能需要将其作为模块运行:
python -m numpy.f2py
如果您运行f2py而没有参数,并且最后一行的numpy 版本与从python -m numpy.f2py打印的 NumPy 版本匹配,则可以使用较短的版本。如果不是这样,或者无法运行f2py,则应该将本指南中提到的所有对f2py的调用替换为较长的版本。
-
包装的三种方式 - 入门指南
-
快速的方式
-
明智的做法
-
快速又聪明的方式
-
-
F2PY 用户指南
-
包装的三种方式 - 入门指南
-
快速的方式
-
明智的做法
-
快速又聪明的方式
-
-
使用 F2PY
-
使用
f2py作为命令行工具 -
Python 模块
numpy.f2py -
自动生成扩展模块
-
-
F2PY 示例
-
F2PY 演练:一个基本的扩展模块
-
一个过滤示例
-
depends关键字示例 -
阅读更多
-
-
-
F2PY 参考手册
-
签名文件
- 签名文件语法
-
在 Python 中使用 F2PY 绑定
-
Fortran 类型对象
-
标量参数
-
字符串参数
-
数组参数
-
回调参数
-
公共块
-
Fortran 90 模块数据
-
可分配数组
-
-
F2PY 和构建系统
-
基本概念
-
构建系统
-
-
高级 F2PY 使用情况
-
向 F2PY 生成的模块添加用户定义函数
-
添加用户定义变量
-
处理 KIND 规范
-
字符字符串
-
-
F2PY 测试套件
- 添加一个测试
-
-
使用 F2PY
-
将
f2py作为命令行工具使用-
1. 签名文件生成
-
2. 扩展模块构建
-
3. 构建一个模块
-
其他选项
-
-
Python 模块
numpy.f2py-
compile -
get_include -
run_main
-
-
自动生成扩展模块
-
-
在 Python 中使用 F2PY 绑定
-
Fortran 类型对象
-
标量参数
-
字符串参数
-
数组参数
-
回调参数
- 解析回调函数的参数
-
公共块
-
Fortran 90 模块数据
-
可分配数组
-
-
签名文件
-
签名文件语法
-
Python 模块块
-
Fortran/C 例程签名
-
类型声明
-
语句
-
属性
-
扩展
-
扩展的字符选择器
-
-
-
F2PY 和构建系统
-
基本概念
-
构建系统
-
通过
numpy.distutils使用 -
通过
meson使用 -
通过
cmake使用 -
通过
scikit-build使用
-
-
-
高级 F2PY 使用情况
-
向 F2PY 生成的模块添加用户定义函数
-
添加用户定义变量
-
处理 KIND 指定符
-
字符字符串
- 假定长度的字符字符串
-
-
F2PY 和 Windows
-
概述
-
基准线
-
Powershell 和 MSVC
-
Windows 商店 Python 路径
-
F2PY 和 Windows Intel Fortran
-
F2PY 和 MSYS2 上的 Windows
-
F2PY 和 Conda on Windows
-
F2PY 和 PGI Fortran on Windows
-
-
开发人员的底层文档
这些文档旨在深入了解 NumPy,面向开发人员。
-
NumPy 数组的内部组织
-
NumPy C 代码解释
-
内存对齐
-
字节交换
-
编写自定义数组容器
-
子类化 ndarray
与 NumPy 的互操作性
NumPy 的 ndarray 对象提供了对数组结构化数据进行操作的高级 API,以及基于 分块内存中存储 的 API 的具体实现。虽然这个 API 功能强大且相当通用,但它的具体实现有限制。随着数据集的增长和 NumPy 在各种新环境和架构中的使用,有些情况下分块内存中存储策略不适用,这导致不同的库为其自己的用途重新实现了这个 API。这包括 GPU 数组 (CuPy)、稀疏数组 (scipy.sparse、PyData/Sparse) 和并行数组 (Dask 数组),以及深度学习框架中类似 NumPy 的实现,如 TensorFlow 和 PyTorch。同样,还有许多项目建立在 NumPy API 之上,用于标记和索引数组 (XArray)、自动微分 (JAX)、遮罩数组 (numpy.ma)、物理单位 (astropy.units、pint、unyt) 等等,这些项目在 NumPy API 的基础上添加了额外的功能。
然而,用户仍然希望使用熟悉的 NumPy API 和最小(理想情况下为零)的移植开销重新使用现有代码来处理这些数组。考虑到这一目标,为具有与 NumPy 匹配的高级 API 的多维数组实现定义了各种协议。
广义上来说,用于与 NumPy 互操作的特性分为三组:
-
将外部对象转换为 ndarray 的方法;
-
将执行延迟从 NumPy 函数转移到另一个数组库的方法;
-
使用 NumPy 函数并返回外部对象实例的方法。
我们在下面描述这些特性。
1. 在 NumPy 中使用任意对象
NumPy API 的第一组互操作特性允许在可能的情况下将外部对象视为 NumPy 数组。当 NumPy 函数遇到外部对象时,它们会依次尝试:
-
缓冲区协议,在 Python C-API 文档 中描述。
-
__array_interface__协议,描述在 此页面 中。作为 Python 缓冲区协议的前身,它定义了一种从其他 C 扩展中访问 NumPy 数组内容的方法。 -
__array__()方法,用于要求任意对象将自身转换为数组。
对于缓冲区和__array_interface__协议,对象描述其内存布局,NumPy 会完成其他一切(如果可能的话,就是零拷贝)。如果这不可能,那么对象本身负责从__array__()返回一个ndarray。
DLPack是用于以一种语言和设备不可知的方式将外部对象转换为 NumPy 数组的另一种协议。NumPy 不会使用 DLPack 隐式地将对象转换为 ndarrays。它提供了函数numpy.from_dlpack,该函数接受任何实现__dlpack__方法的对象,并输出一个 NumPy ndarray(通常是输入对象的数据缓冲区的视图)。DLPack 的 Python 规范页面详细解释了__dlpack__协议。
数组接口协议
数组接口协议定义了一种让类似数组对象重新使用彼此的数据缓冲区的方式。其实现依赖于以下属性或方法的存在:
-
__array_interface__:包含数组样对象的形状、元素类型,可选的数据缓冲区地址和步长的 Python 字典; -
__array__(): 返回数组样对象的 NumPy ndarray 视图的方法;
可以直接检查__array_interface__属性:
>>> import numpy as np
>>> x = np.array([1, 2, 5.0, 8])
>>> x.__array_interface__
{'data': (94708397920832, False), 'strides': None, 'descr': [('', '<f8')], 'typestr': '<f8', 'shape': (4,), 'version': 3}
__array_interface__属性还可以用于就地操纵对象数据:
>>> class wrapper():
... pass
...
>>> arr = np.array([1, 2, 3, 4])
>>> buf = arr.__array_interface__
>>> buf
{'data': (140497590272032, False), 'strides': None, 'descr': [('', '<i8')], 'typestr': '<i8', 'shape': (4,), 'version': 3}
>>> buf['shape'] = (2, 2)
>>> w = wrapper()
>>> w.__array_interface__ = buf
>>> new_arr = np.array(w, copy=False)
>>> new_arr
array([[1, 2],
[3, 4]])
我们可以检查arr和new_arr是否共享相同的数据缓冲区:
>>> new_arr[0, 0] = 1000
>>> new_arr
array([[1000, 2],
[ 3, 4]])
>>> arr
array([1000, 2, 3, 4])
__array__()方法
__array__()方法确保任何类似于 NumPy 的对象(数组,任何公开数组接口的对象,其__array__()方法返回数组或任何嵌套序列的对象)实现它都可以用作 NumPy 数组。如果可能,这意味着使用__array__()来创建数组样对象的 NumPy ndarray 视图。否则,这将复制数据到一个新的 ndarray 对象中。这并不是最佳选择,因为强制将数组强制转换为 ndarrays 可能会导致性能问题,或者需要复制和丢失元数据,原始对象以及原始对象可能具有的任何属性/行为都会丢失。
要查看包括使用__array__()的自定义数组实现的示例,请参见编写自定义数组容器。
DLPack 协议
DLPack协议定义了跨 strided n 维数组对象的内存布局。它提供以下语法以进行数据交换:
-
一个
numpy.from_dlpack函数,它接受带有__dlpack__方法的(数组)对象,并使用该方法来构建包含来自x的数据的新数组。 -
数组对象上的
__dlpack__(self, stream=None)和__dlpack_device__方法,它们将在from_dlpack中调用,以查询数组所在的设备(在多个 GPU 的情况下可能需要传入正确的流),以及访问数据。
与缓冲区协议不同,DLPack 允许交换包含非 CPU 设备(例如 Vulkan 或 GPU)上数据的数组。由于 NumPy 仅支持 CPU,它只能转换数据存在于 CPU 上的对象。但其他库,如PyTorch和 CuPy,可能使用该协议在 GPU 上交换数据。
2. 在不转换的情况下操作外部对象
NumPy API 定义的第二组方法允许我们将执行从 NumPy 函数延迟到另一个数组库。
考虑以下函数。
>>> import numpy as np
>>> def f(x):
... return np.mean(np.exp(x))
请注意,np.exp是一个 ufunc,这意味着它以逐元素的方式作用于 ndarrays。另一方面,np.mean沿着数组的一个轴进行操作。
我们可以将f直接应用于一个 NumPy ndarray 对象:
>>> x = np.array([1, 2, 3, 4])
>>> f(x)
21.1977562209304
我们希望这个函数能够在任何类似于 NumPy 的数组对象上同样有效。
NumPy 允许类通过以下接口指示它希望以自定义方式进行计算:
-
__array_ufunc__: 允许第三方对象支持和覆盖 ufuncs。 -
__array_function__: 用于覆盖通用函数中不涵盖的 NumPy 功能的默认操作。
只要外部对象实现了__array_ufunc__或__array_function__协议,就可以在它们上操作而无需进行显式转换。
__array_ufunc__ 协议
通用函数(或简写为 ufunc)是一个对函数进行“矢量化”封装的函数,它接受固定数量的特定输入并产生固定数量的特定输出。如果非 ndarray 对象的输入定义了__array_ufunc__方法,则控制完全传递给该函数,即 ufunc 将被覆盖。在该(非 ndarray)对象上定义的__array_ufunc__方法可以访问 NumPy ufunc。由于 ufunc 具有明确定义的结构,外部__array_ufunc__方法可能依赖 ufunc 属性,如.at()、.reduce()等。
子类可以通过覆盖默认的ndarray.__array_ufunc__方法来覆盖在其上执行 NumPy ufuncs 时发生的情况。这个方法将代替 ufunc 的执行,并且应该返回操作的结果,或者如果请求的操作未实现,则返回NotImplemented。
__array_function__ 协议
为了足够覆盖 NumPy API 以支持下游项目,需要超越 __array_ufunc__ 并实现一个协议,允许 NumPy 函数的参数控制并将执行转移到另一个函数(例如 GPU 或并行实现),以安全和一致的方式跨项目进行。
__array_function__的语义与__array_ufunc__非常相似,只是操作由任意可调用对象指定,而不是由 ufunc 实例和方法指定。更多细节,请参见NEP 18 — NumPy 高级数组函数的调度机制,其中包含 NumPy Enhancement Proposals。"
3. 返回外部对象
第三种特性集旨在使用 NumPy 函数实现,然后将返回值转换为外部对象的实例。__array_finalize__ 和 __array_wrap__ 方法在幕后起作用,以确保可以根据需要指定 NumPy 函数的返回类型。
__array_finalize__ 方法是 NumPy 提供的机制,允许子类处理新实例被创建的各种方式。每当系统从 ndarray 的子类(子类型)内部分配新数组时,都会调用此方法。它可以用于在构建后更改属性,或从“父类”更新元信息。
__array_wrap__ 方法“包装了行动”,意思是允许任何对象(如用户定义的函数)设置其返回值的类型并更新属性和元数据。这可以被视为__array__方法的相反。在每个实现__array_wrap__的对象的最高数组优先级或指定的输出对象之后,将对输入对象调用此方法。 __array_priority__属性用于确定在返回对象的 Python 类型存在多种可能性的情况下要返回什么类型的对象。例如,子类可以选择使用此方法将输出数组转换为子类的实例,并在将数组返回给用户之前更新元数据。
有关这些方法的更多信息,请参阅 ndarray 子类化 和 ndarray 子类型的特定特性。
互操作性示例
示例:Pandas Series 对象
考虑以下内容:
>>> import pandas as pd
>>> ser = pd.Series([1, 2, 3, 4])
>>> type(ser)
pandas.core.series.Series
现在,ser 不是一个 ndarray,但因为它实现了 array_ufunc 协议,我们可以将 ufunc 应用于它,好像它是一个 ndarray 一样:
>>> np.exp(ser)
0 2.718282
1 7.389056
2 20.085537
3 54.598150
dtype: float64
>>> np.sin(ser)
0 0.841471
1 0.909297
2 0.141120
3 -0.756802
dtype: float64
我们甚至可以与其他 ndarray 执行操作:
>>> np.add(ser, np.array([5, 6, 7, 8]))
0 6
1 8
2 10
3 12
dtype: int64
>>> f(ser)
21.1977562209304
>>> result = ser.__array__()
>>> type(result)
numpy.ndarray
示例:PyTorch 张量
PyTorch 是一个针对使用 GPU 和 CPU 进行深度学习的优化张量库。PyTorch 数组通常被称为 张量。张量类似于 NumPy 的 ndarrays,只是张量可以在 GPU 或其他硬件加速器上运行。事实上,张量和 NumPy 数组通常可以共享相同的底层内存,消除了复制数据的需要。
>>> import torch
>>> data = [[1, 2],[3, 4]]
>>> x_np = np.array(data)
>>> x_tensor = torch.tensor(data)
请注意 x_np 和 x_tensor 是不同种类的对象:
>>> x_np
array([[1, 2],
[3, 4]])
>>> x_tensor
tensor([[1, 2],
[3, 4]])
然而,我们可以将 PyTorch 张量视为 NumPy 数组,而无需显式转换:
>>> np.exp(x_tensor)
tensor([[ 2.7183, 7.3891],
[20.0855, 54.5982]], dtype=torch.float64)
此外,请注意该函数的返回类型与初始数据类型兼容。
警告
尽管将 ndarrays 和张量混合使用可能很方便,但不建议这样做。它对于非 CPU 张量不起作用,在一些边缘情况下会有意外的行为。用户应该优先显式地将 ndarray 转换为张量。
注意
PyTorch 没有实现 __array_function__ 或 __array_ufunc__。在底层,Tensor.__array__() 方法返回张量数据缓冲区的 NumPy ndarray 视图。详情请参阅 此问题 和 torch_function 实现。
还需注意,即使 torch.Tensor 不是 ndarray 的子类,我们也可以看到 __array_wrap__ 在这里发挥作用:
>>> import torch
>>> t = torch.arange(4)
>>> np.abs(t)
tensor([0, 1, 2, 3])
PyTorch 实现了 __array_wrap__ 来能够从 NumPy 函数中获取张量,并且我们可以直接修改它以控制从这些函数中返回哪种类型的对象。
例如:CuPy 数组
CuPy 是一个用于 GPU 加速计算的 NumPy/SciPy 兼容数组库。CuPy 通过实现 cupy.ndarray 实现了 NumPy 接口的子集,与 NumPy ndarrays 对应。
>>> import cupy as cp
>>> x_gpu = cp.array([1, 2, 3, 4])
cupy.ndarray 对象实现了 __array_ufunc__ 接口。这使得可以将 NumPy ufuncs 应用于 CuPy 数组(这将推迟操作到与 ufunc 匹配的 CuPy CUDA/ROCm 实现):
>>> np.mean(np.exp(x_gpu))
array(21.19775622)
请注意这些操作的返回类型仍与初始类型一致:
>>> arr = cp.random.randn(1, 2, 3, 4).astype(cp.float32)
>>> result = np.sum(arr)
>>> print(type(result))
<class 'cupy._core.core.ndarray'>
请参阅 CuPy 文档中的此页面以获取详细信息。
cupy.ndarray 也实现了 __array_function__ 接口,这意味着可以执行诸如
>>> a = np.random.randn(100, 100)
>>> a_gpu = cp.asarray(a)
>>> qr_gpu = np.linalg.qr(a_gpu)
CuPy 在 cupy.ndarray 对象上实现了许多 NumPy 函数,但并非全部。详情请参阅 CuPy 文档。
例如:Dask 数组
Dask 是 Python 中用于并行计算的灵活库。Dask Array 使用分块算法实现了 NumPy ndarray 接口的子集,将大数组切分成许多小数组。这允许使用多个核心对大于内存的数组进行计算。
Dask 支持 __array__() 和 __array_ufunc__。
>>> import dask.array as da
>>> x = da.random.normal(1, 0.1, size=(20, 20), chunks=(10, 10))
>>> np.mean(np.exp(x))
dask.array<mean_agg-aggregate, shape=(), dtype=float64, chunksize=(), chunktype=numpy.ndarray>
>>> np.mean(np.exp(x)).compute()
5.090097550553843
注意
Dask 是惰性评估的,只有在通过调用 compute() 请求时,才会计算计算结果。
详细了解 Dask 数组文档 和 Dask 数组与 NumPy 数组互操作性的范围。
示例:DLPack
几个 Python 数据科学库实现了 __dlpack__ 协议。其中包括 PyTorch 和 CuPy。可以在 DLPack 文档的这一页 找到实现此协议的库的完整列表。
将 PyTorch CPU 张量转换为 NumPy 数组:
>>> import torch
>>> x_torch = torch.arange(5)
>>> x_torch
tensor([0, 1, 2, 3, 4])
>>> x_np = np.from_dlpack(x_torch)
>>> x_np
array([0, 1, 2, 3, 4])
>>> # note that x_np is a view of x_torch
>>> x_torch[1] = 100
>>> x_torch
tensor([ 0, 100, 2, 3, 4])
>>> x_np
array([ 0, 100, 2, 3, 4])
导入的数组是只读的,因此无法进行写入或原地操作:
>>> x.flags.writeable
False
>>> x_np[1] = 1
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
ValueError: assignment destination is read-only
为了原地操作导入的数组,必须创建副本,但这将意味着复制内存。对于非常大的数组,请不要这样做:
>>> x_np_copy = x_np.copy()
>>> x_np_copy.sort() # works
注意
请注意,由于 NumPy 不支持 GPU 设备,无法将 GPU 张量转换为 NumPy 数组:
>>> x_torch = torch.arange(5, device='cuda')
>>> np.from_dlpack(x_torch)
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
RuntimeError: Unsupported device in DLTensor.
但是,如果两个库都支持数据缓冲区所在的设备,则可以使用 __dlpack__ 协议(例如 PyTorch 和 CuPy):
>>> x_torch = torch.arange(5, device='cuda')
>>> x_cupy = cupy.from_dlpack(x_torch)
类似地,可以将 NumPy 数组转换为 PyTorch 张量:
>>> x_np = np.arange(5)
>>> x_torch = torch.from_dlpack(x_np)
只读数组无法导出:
>>> x_np = np.arange(5)
>>> x_np.flags.writeable = False
>>> torch.from_dlpack(x_np)
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
File ".../site-packages/torch/utils/dlpack.py", line 63, in from_dlpack
dlpack = ext_tensor.__dlpack__()
TypeError: NumPy currently only supports dlpack for writeable arrays
进一步阅读
-
数组接口协议
-
编写自定义数组容器
-
特殊属性和方法(关于
__array_ufunc__和__array_function__协议的详细信息) -
子类化 ndarray(关于
__array_wrap__和__array_finalize__方法的详细信息) -
ndarray 子类型化的特定功能(有关
__array_finalize__、__array_wrap__和__array_priority__实现的更多详细信息)
1. 在 NumPy 中使用任意对象
NumPy API 的第一组互操作性功能允许在可能的情况下将外部对象视为 NumPy 数组。当 NumPy 函数遇到外部对象时,它们将按顺序尝试:
-
缓冲区协议,在 Python C-API 文档中 有描述。
-
__array_interface__协议,在 这个页面 有描述。作为 Python 缓冲区协议的前身,它定义了从其他 C 扩展中访问 NumPy 数组内容的方法。 -
__array__()方法,请求任意对象将自身转换为数组。
对于缓冲区和 __array_interface__ 协议,对象描述其内存布局,NumPy 执行其他所有操作(如果可能,零拷贝)。 如果不可能,则对象本身负责从 __array__() 返回 ndarray。
DLPack 是将外部对象以一种与语言和设备无关的方式转换为 NumPy 数组的另一种协议。 NumPy 不会使用 DLPack 将对象隐式转换为 ndarrays。 它提供了函数 numpy.from_dlpack ,该函数接受实现 __dlpack__ 方法的任何对象,并输出 NumPy ndarray(通常是输入对象数据缓冲区的视图)。 DLPack 的 Python 规范 页面详细说明了 __dlpack__ 协议。
数组接口协议
数组接口协议 定义了数组样对象重用彼此数据缓冲区的方式。 其实现依赖于以下属性或方法的存在:
-
__array_interface__:一个 Python 字典,包含类似数组对象的形状、元素类型,以及可选的数据缓冲地址和步幅; -
__array__():返回类似数组对象的 NumPy ndarray 视图的方法;
可以直接检查 __array_interface__ 属性:
>>> import numpy as np
>>> x = np.array([1, 2, 5.0, 8])
>>> x.__array_interface__
{'data': (94708397920832, False), 'strides': None, 'descr': [('', '<f8')], 'typestr': '<f8', 'shape': (4,), 'version': 3}
__array_interface__ 属性还可用于就地操作对象数据:
>>> class wrapper():
... pass
...
>>> arr = np.array([1, 2, 3, 4])
>>> buf = arr.__array_interface__
>>> buf
{'data': (140497590272032, False), 'strides': None, 'descr': [('', '<i8')], 'typestr': '<i8', 'shape': (4,), 'version': 3}
>>> buf['shape'] = (2, 2)
>>> w = wrapper()
>>> w.__array_interface__ = buf
>>> new_arr = np.array(w, copy=False)
>>> new_arr
array([[1, 2],
[3, 4]])
我们可以检查 arr 和 new_arr 是否共享相同的数据缓冲区:
>>> new_arr[0, 0] = 1000
>>> new_arr
array([[1000, 2],
[ 3, 4]])
>>> arr
array([1000, 2, 3, 4])
__array__() 方法
__array__() 方法确保任何类似 NumPy 的对象(数组、公开数组接口的任何对象、其 __array__() 方法返回数组的对象或任何嵌套序列),只要实现它,就可以用作 NumPy 数组。 如果可能,这将意味着使用 __array__() 来创建数组对象的 NumPy ndarray 视图。 否则,这将复制数据到一个新的 ndarray 对象中。 这不是最佳的,因为将数组强制转换为 ndarrays 可能会导致性能问题或创建副本和元数据丢失,因为原始对象及其可能具有的任何属性/行为都会丢失。
要查看自定义数组实现的示例,包括使用 __array__() 的用法,请参见 编写自定义数组容器。
DLPack 协议
DLPack 协议定义了分块的 n 维数组对象的内存布局。 它为数据交换提供了以下语法:
-
numpy.from_dlpack函数接受具有__dlpack__方法的(数组)对象,并使用该方法构造一个包含来自x的数据的新数组。 -
数组对象上的
__dlpack__(self, stream=None)和__dlpack_device__方法将从from_dlpack中调用,以查询数组所在的设备(可能需要传递正确的流,例如在多个 GPU 的情况下),并访问数据。
与缓冲区协议不同,DLPack 允许交换包含在 CPU 之外设备上的数据的数组(例如 Vulkan 或 GPU)。由于 NumPy 仅支持 CPU,因此它只能转换其数据存在于 CPU 的对象。但其他库,如PyTorch和CuPy,可以使用这个协议在 GPU 上交换数据。
数组接口协议
数组接口协议定义了类似数组的对象重复使用对方的数据缓冲区的方式。其实现依赖于以下属性或方法的存在:
-
__array_interface__:一个包含数组-like 对象的形状,元素类型,和可选的数据缓冲区地址和步幅的 Python 字典; -
__array__():返回类似数组的对象的 NumPy ndarray 视图的方法;
可以直接检查__array_interface__属性:
>>> import numpy as np
>>> x = np.array([1, 2, 5.0, 8])
>>> x.__array_interface__
{'data': (94708397920832, False), 'strides': None, 'descr': [('', '<f8')], 'typestr': '<f8', 'shape': (4,), 'version': 3}
__array_interface__属性还可以用于原地操作对象数据:
>>> class wrapper():
... pass
...
>>> arr = np.array([1, 2, 3, 4])
>>> buf = arr.__array_interface__
>>> buf
{'data': (140497590272032, False), 'strides': None, 'descr': [('', '<i8')], 'typestr': '<i8', 'shape': (4,), 'version': 3}
>>> buf['shape'] = (2, 2)
>>> w = wrapper()
>>> w.__array_interface__ = buf
>>> new_arr = np.array(w, copy=False)
>>> new_arr
array([[1, 2],
[3, 4]])
我们可以检查arr和new_arr是否共享相同的数据缓冲区:
>>> new_arr[0, 0] = 1000
>>> new_arr
array([[1000, 2],
[ 3, 4]])
>>> arr
array([1000, 2, 3, 4])
__array__()方法
__array__()方法确保任何类似 NumPy 的对象(数组,任何暴露数组接口的对象,其__array__()方法返回数组或任何嵌套序列的对象)都可以用作 NumPy 数组。如果可能的话,这意味着使用__array__()来创建类似数组对象的 NumPy ndarray 视图。否则,这将复制数据到一个新的 ndarray 对象中。这并不是最佳情况,因为将数组强制转换为 ndarrays 可能会导致性能问题或创建需要复制和丢失元数据的情况,因为原始对象及其可能具有的任何属性/行为都会丢失。
要查看包括使用__array__()的自定义数组实现的示例,请参见编写自定义数组容器。
DLPack 协议
DLPack协议定义了步进式 n 维数组对象的内存布局。它为数据交换提供了以下语法:
-
numpy.from_dlpack函数,接受具有__dlpack__方法的(数组)对象,并使用该方法来构建包含x数据的新数组。 -
数组对象上的
__dlpack__(self, stream=None)和__dlpack_device__方法将从from_dlpack中调用,以查询数组所在的设备(可能需要传递正确的流,例如在多个 GPU 的情况下),并访问数据。
与缓冲协议不同,DLPack 允许交换包含设备上的数据(如 Vulkan 或 GPU)的数组。由于 NumPy 仅支持 CPU,因此只能转换数据存在于 CPU 上的对象。但其他库,如 PyTorch 和 CuPy,可以使用该协议在 GPU 上交换数据。
2. 在不转换的情况下操作外部对象
NumPy API 定义的第二组方法允许我们将一个 NumPy 函数的执行延迟到另一个数组库。
考虑以下函数。
>>> import numpy as np
>>> def f(x):
... return np.mean(np.exp(x))
请注意,np.exp 是一个 ufunc,这意味着它按元素方式在 ndarrays 上操作。另一方面,np.mean 沿数组的一个轴操作。
我们可以直接将 f 应用于 NumPy ndarray 对象:
>>> x = np.array([1, 2, 3, 4])
>>> f(x)
21.1977562209304
我们希望这个函数在任何类似 NumPy 的数组对象上都能很好地工作。
NumPy 允许一个类通过以下接口指示它想通过自定义方式处理计算:
-
__array_ufunc__:允许第三方对象支持和覆盖 ufuncs。 -
__array_function__:用于处理通用函数的 NumPy 功能的总称,该功能不受通用函数协议__array_ufunc__的覆盖。
只要外部对象实现了 __array_ufunc__ 或 __array_function__ 协议,就可以在它们上操作而无需进行显式转换。
__array_ufunc__ 协议
通用函数(ufunc 简写)是一个“向量化”包装器,用于接收固定数量的特定输入并产生固定数量的特定输出的函数。如果不是所有的输入参数都是 ndarray,ufunc 的输出(及其方法)不一定是 ndarray。实际上,如果任何输入定义了 __array_ufunc__ 方法,控制权将完全传递给该函数,即通用函数被覆盖。在该(非 ndarray)对象上定义的 __array_ufunc__ 方法可以访问 NumPy ufunc。由于通用函数有明确定义的结构,外部的 __array_ufunc__ 方法可以依赖于类似 .at()、.reduce() 等的 ufunc 属性。
通过重写默认的 ndarray.__array_ufunc__ 方法,子类可以覆盖在其上执行 NumPy ufuncs 时的操作方式。这个方法会代替 ufunc 被执行,并应该返回操作的结果,或者在请求的操作未被实现时返回 NotImplemented。
__array_function__ 协议
为了实现足够的 NumPy API 覆盖范围以支持下游项目,需要超出__array_ufunc__并实现一种协议,允许 NumPy 函数的参数控制并将执行转移到另一个函数(例如 GPU 或并行实现),以一种安全和一致的方式跨项目进行。
__array_function__ 的语义与 __array_ufunc__ 非常相似,只是操作由任意可调用对象指定,而不是 ufunc 实例和方法。具体详情请参见NEP 18 — NumPy 高级数组函数的调度机制。
__array_ufunc__ 协议
通用函数(或简称 ufunc)是一个对函数进行“矢量化”封装的函数,它接受固定数量的特定输入,并产生固定数量的特定输出。 如果所有输入参数都不是 ndarray,则 ufunc 的输出(及其方法)未必是 ndarray。 实际上,如果任何输入定义了__array_ufunc__方法,则完全将控制权传递给该函数,即 ufunc 被覆盖。定义在那个(非 ndarray)对象上的__array_ufunc__方法可以访问 NumPy ufunc。 由于 ufuncs 有明确定义的结构,外部__array_ufunc__方法可以依赖于 ufunc 属性,例如.at()、.reduce()和其他属性。
子类可以通过覆盖默认的ndarray.__array_ufunc__方法来在执行 NumPy ufuncs 时改写其行为。这个方法将代替 ufunc 的执行,并应该返回操作的结果,或者如果请求的操作未实现,则返回NotImplemented。
__array_function__ 协议
为了实现足够的 NumPy API 覆盖范围以支持下游项目,需要超出__array_ufunc__并实现一种协议,允许 NumPy 函数的参数控制并将执行转移到另一个函数(例如 GPU 或并行实现),以一种安全和一致的方式跨项目进行。
__array_function__ 的语义与 __array_ufunc__ 非常相似,只是操作由任意可调用对象指定,而不是 ufunc 实例和方法。具体详情请参见NEP 18 — NumPy 高级数组函数的调度机制。
3. 返回外部对象
第三种特性集意在使用 NumPy 函数实现,然后将返回值转换回外部对象的实例。__array_finalize__和__array_wrap__方法在幕后起作用,以确保可以根据需要指定 NumPy 函数的返回类型。
__array_finalize__方法是 NumPy 提供的机制,允许子类处理创建新实例的各种方式。每当系统从数组的子类(子类型)的对象内部分配新数组时,就会调用此方法。它可用于在构造后更改属性,或者从“父级”更新元信息。
__array_wrap__方法“包装了操作”,在允许任何对象(如用户定义的函数)设置其返回值类型和更新属性和元数据方面发挥作用。这可以看作是__array__方法的相反。在实现__array_wrap__的每个对象的末尾,将对具有最高数组优先级的输入对象调用此方法,或者如果指定了输出对象,则在输出对象上调用此方法。__array_priority__属性用于确定在返回对象的 Python 类型存在多种可能性的情况下应返回什么类型的对象。例如,子类可能选择使用此方法将输出数组变换为子类实例并在返回数组给用户之前更新元数据。
有关这些方法的更多信息,请参阅子类化 ndarray 和 ndarray 子类型的特定特征。
互操作性示例
例子:Pandas Series对象
考虑以下内容:
>>> import pandas as pd
>>> ser = pd.Series([1, 2, 3, 4])
>>> type(ser)
pandas.core.series.Series
现在,ser 不是一个 ndarray,但由于它实现了 array_ufunc 协议,我们可以将 ufuncs 应用于它,就好像它是一个 ndarray 一样:
>>> np.exp(ser)
0 2.718282
1 7.389056
2 20.085537
3 54.598150
dtype: float64
>>> np.sin(ser)
0 0.841471
1 0.909297
2 0.141120
3 -0.756802
dtype: float64
我们甚至可以对其他 ndarray 执行操作:
>>> np.add(ser, np.array([5, 6, 7, 8]))
0 6
1 8
2 10
3 12
dtype: int64
>>> f(ser)
21.1977562209304
>>> result = ser.__array__()
>>> type(result)
numpy.ndarray
例子:PyTorch 张量
PyTorch是一个针对使用 GPU 和 CPU 进行深度学习的优化张量库。PyTorch 数组通常被称为张量。张量类似于 NumPy 的 ndarray,只不过张量可以在 GPU 或其他硬件加速器上运行。实际上,张量和 NumPy 数组通常可以共享相同的底层内存,消除了复制数据的需求。
>>> import torch
>>> data = [[1, 2],[3, 4]]
>>> x_np = np.array(data)
>>> x_tensor = torch.tensor(data)
注意x_np和x_tensor是不同类型的对象:
>>> x_np
array([[1, 2],
[3, 4]])
>>> x_tensor
tensor([[1, 2],
[3, 4]])
但是,我们可以将 PyTorch 张量视为 NumPy 数组,而无需显式转换:
>>> np.exp(x_tensor)
tensor([[ 2.7183, 7.3891],
[20.0855, 54.5982]], dtype=torch.float64)
此外,还要注意此函数的返回类型与初始数据类型兼容。
警告
虽然混合使用 ndarray 和张量可能很方便,但不建议这样做。它对非 CPU 张量不起作用,并且在一些特殊情况下会产生意外行为。用户应优先显式将 ndarray 转换为张量。
注意
PyTorch 不实现__array_function__或__array_ufunc__。在底层,Tensor.__array__()方法返回一个 NumPy ndarray,作为张量数据缓冲区的视图。有关详细信息,请参阅此问题和torch_function 实现。
还要注意,即使torch.Tensor不是 ndarray 的子类,我们也可以在这里看到__array_wrap__的实际运行:
>>> import torch
>>> t = torch.arange(4)
>>> np.abs(t)
tensor([0, 1, 2, 3])
PyTorch 实现了__array_wrap__以便从 NumPy 函数获取张量,并且我们可以直接修改它以控制从这些函数返回哪种类型的对象。
例:CuPy 数组
CuPy 是用于 GPU 加速计算的 NumPy/SciPy 兼容数组库。CuPy 通过实现cupy.ndarray实现了 NumPy 接口的子集,与 NumPy ndarrays 对应。
>>> import cupy as cp
>>> x_gpu = cp.array([1, 2, 3, 4])
cupy.ndarray对象实现了__array_ufunc__接口。这使得可以对 CuPy 数组应用 NumPy ufunc(这将将操作推迟到对应的 CuPy CUDA/ROCm 实现的 ufunc):
>>> np.mean(np.exp(x_gpu))
array(21.19775622)
请注意,这些操作的返回类型仍与初始类型保持一致:
>>> arr = cp.random.randn(1, 2, 3, 4).astype(cp.float32)
>>> result = np.sum(arr)
>>> print(type(result))
<class 'cupy._core.core.ndarray'>
cupy.ndarray还实现了__array_function__接口,这意味着可以进行诸如
>>> a = np.random.randn(100, 100)
>>> a_gpu = cp.asarray(a)
>>> qr_gpu = np.linalg.qr(a_gpu)
CuPy 在cupy.ndarray对象上实现了许多 NumPy 函数,但不是全部。有关详细信息,请参阅CuPy 文档。
例:Dask 数组
Dask 是 Python 中用于并行计算的灵活库。Dask 数组使用分块算法实现了 NumPy ndarray 接口的子集,将大数组切割成许多小数组。这允许使用多个核心对大于内存的数组进行计算。
Dask 支持__array__()和__array_ufunc__。
>>> import dask.array as da
>>> x = da.random.normal(1, 0.1, size=(20, 20), chunks=(10, 10))
>>> np.mean(np.exp(x))
dask.array<mean_agg-aggregate, shape=(), dtype=float64, chunksize=(), chunktype=numpy.ndarray>
>>> np.mean(np.exp(x)).compute()
5.090097550553843
请注意
Dask 是延迟评估的,直到通过调用compute()要求计算结果才会计算。
有关详细信息,请参阅Dask 数组文档以及Dask 数组与 NumPy 数组的互操作性范围。
例:DLPack
几个 Python 数据科学库实现了__dlpack__协议。其中包括PyTorch和CuPy。可以在DLPack 文档的此页面找到实现此协议的库的完整列表。
将 PyTorch CPU 张量转换为 NumPy 数组:
>>> import torch
>>> x_torch = torch.arange(5)
>>> x_torch
tensor([0, 1, 2, 3, 4])
>>> x_np = np.from_dlpack(x_torch)
>>> x_np
array([0, 1, 2, 3, 4])
>>> # note that x_np is a view of x_torch
>>> x_torch[1] = 100
>>> x_torch
tensor([ 0, 100, 2, 3, 4])
>>> x_np
array([ 0, 100, 2, 3, 4])
导入的数组是只读的,因此写入或原地操作将失败:
>>> x.flags.writeable
False
>>> x_np[1] = 1
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
ValueError: assignment destination is read-only
必须创建副本才能对导入的数组进行原地操作,但这将意味着复制内存。对于非常大的数组不要这样做:
>>> x_np_copy = x_np.copy()
>>> x_np_copy.sort() # works
请注意
请注意,GPU 张量不能转换为 NumPy 数组,因为 NumPy 不支持 GPU 设备:
>>> x_torch = torch.arange(5, device='cuda')
>>> np.from_dlpack(x_torch)
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
RuntimeError: Unsupported device in DLTensor.
但是,如果这两个库都支持数据缓冲区所在的设备,则可以使用__dlpack__协议(例如PyTorch和CuPy):
>>> x_torch = torch.arange(5, device='cuda')
>>> x_cupy = cupy.from_dlpack(x_torch)
同样,NumPy 数组可以转换为 PyTorch 张量:
>>> x_np = np.arange(5)
>>> x_torch = torch.from_dlpack(x_np)
只读数组无法导出:
>>> x_np = np.arange(5)
>>> x_np.flags.writeable = False
>>> torch.from_dlpack(x_np)
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
File ".../site-packages/torch/utils/dlpack.py", line 63, in from_dlpack
dlpack = ext_tensor.__dlpack__()
TypeError: NumPy currently only supports dlpack for writeable arrays
示例:Pandas Series对象
考虑以下内容:
>>> import pandas as pd
>>> ser = pd.Series([1, 2, 3, 4])
>>> type(ser)
pandas.core.series.Series
现在,ser不是一个 ndarray,但因为它实现了__array_ufunc__协议,我们就可以像处理 ndarray 一样对其应用 ufunc:
>>> np.exp(ser)
0 2.718282
1 7.389056
2 20.085537
3 54.598150
dtype: float64
>>> np.sin(ser)
0 0.841471
1 0.909297
2 0.141120
3 -0.756802
dtype: float64
我们甚至可以对其他 ndarrays 执行操作:
>>> np.add(ser, np.array([5, 6, 7, 8]))
0 6
1 8
2 10
3 12
dtype: int64
>>> f(ser)
21.1977562209304
>>> result = ser.__array__()
>>> type(result)
numpy.ndarray
示例:PyTorch 张量
PyTorch是一个用于在 GPU 和 CPU 上进行深度学习的优化张量库。PyTorch 数组通常被称为张量。张量类似于 NumPy 的 ndarrays,唯一的区别在于张量可以在 GPU 或其他硬件加速器上运行。实际上,张量和 NumPy 数组通常可以共享相同的底层存储器,消除了复制数据的需求。
>>> import torch
>>> data = [[1, 2],[3, 4]]
>>> x_np = np.array(data)
>>> x_tensor = torch.tensor(data)
注意x_np和x_tensor是不同类型的对象:
>>> x_np
array([[1, 2],
[3, 4]])
>>> x_tensor
tensor([[1, 2],
[3, 4]])
然而,我们可以将 PyTorch 张量视为 NumPy 数组,无需进行显式转换:
>>> np.exp(x_tensor)
tensor([[ 2.7183, 7.3891],
[20.0855, 54.5982]], dtype=torch.float64)
同样,请注意此函数的返回类型与初始数据类型兼容。
警告
虽然混合使用 ndarrays 和张量可能很方便,但不建议这样做。它不适用于非 CPU 张量,并且在极端情况下会出现意外行为。用户应该更倾向于显式将 ndarray 转换为张量。
注意
PyTorch 不实现__array_function__或__array_ufunc__。在内部,Tensor.__array__()方法返回一个 NumPy ndarray 作为张量数据缓冲区的视图。有关详细信息,请参见此问题和torch_function 实现。
还要注意,即使torch.Tensor不是 ndarray 的子类,我们也可以在这里看到__array_wrap__的功能:
>>> import torch
>>> t = torch.arange(4)
>>> np.abs(t)
tensor([0, 1, 2, 3])
PyTorch 实现了__array_wrap__以便能够从 NumPy 函数中取回张量,并且我们可以直接修改它以控制从这些函数返回哪种类型的对象。
示例:CuPy 数组
CuPy 是一个用于 GPU 加速计算的与 NumPy/SciPy 兼容的数组库。CuPy 通过实现cupy.ndarray,与 NumPy ndarrays 对应的对象实现了 NumPy 接口的子集。
>>> import cupy as cp
>>> x_gpu = cp.array([1, 2, 3, 4])
cupy.ndarray对象实现了__array_ufunc__接口。这使得可以将 NumPy ufuncs 应用于 CuPy 数组(这将将操作延迟到 ufunc 的匹配 CuPy CUDA/ROCm 实现):
>>> np.mean(np.exp(x_gpu))
array(21.19775622)
请注意这些操作的返回类型仍与初始类型一致:
>>> arr = cp.random.randn(1, 2, 3, 4).astype(cp.float32)
>>> result = np.sum(arr)
>>> print(type(result))
<class 'cupy._core.core.ndarray'>
有关详细信息,请参见CuPy 文档中的此页面。
cupy.ndarray还实现了__array_function__接口,这意味着可以进行诸如
>>> a = np.random.randn(100, 100)
>>> a_gpu = cp.asarray(a)
>>> qr_gpu = np.linalg.qr(a_gpu)
CuPy 在cupy.ndarray对象上实现了许多 NumPy 函数,但并非都实现。有关详细信息,请参阅CuPy 文档。
示例:Dask 数组
Dask 是 Python 中用于并行计算的灵活库。Dask Array 使用分块算法实现了 NumPy ndarray 接口的子集,将大数组切分为许多小数组。这使得可以使用多个核心对大于内存大小的数组进行计算。
Dask 支持__array__()和__array_ufunc__。
>>> import dask.array as da
>>> x = da.random.normal(1, 0.1, size=(20, 20), chunks=(10, 10))
>>> np.mean(np.exp(x))
dask.array<mean_agg-aggregate, shape=(), dtype=float64, chunksize=(), chunktype=numpy.ndarray>
>>> np.mean(np.exp(x)).compute()
5.090097550553843
注意
Dask 是惰性计算的,计算的结果直到通过调用compute()来要求计算时才计算。
有关详细信息,请参阅 Dask 数组文档 和 Dask 数组与 NumPy 数组互操作性的范围。
示例:DLPack
几个 Python 数据科学库都实现了__dlpack__协议,其中包括PyTorch和CuPy。可以在DLPack 文档的此页面找到实现此协议的库的完整列表。
将 PyTorch CPU 张量转换为 NumPy 数组:
>>> import torch
>>> x_torch = torch.arange(5)
>>> x_torch
tensor([0, 1, 2, 3, 4])
>>> x_np = np.from_dlpack(x_torch)
>>> x_np
array([0, 1, 2, 3, 4])
>>> # note that x_np is a view of x_torch
>>> x_torch[1] = 100
>>> x_torch
tensor([ 0, 100, 2, 3, 4])
>>> x_np
array([ 0, 100, 2, 3, 4])
导入的数组是只读的,因此写入或就地操作将失败:
>>> x.flags.writeable
False
>>> x_np[1] = 1
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
ValueError: assignment destination is read-only
为了就地操作导入的数组,必须创建副本,但这将意味着内存复制。对于非常大的数组不要这样做:
>>> x_np_copy = x_np.copy()
>>> x_np_copy.sort() # works
注意
注意 GPU 张量无法转换为 NumPy 数组,因为 NumPy 不支持 GPU 设备:
>>> x_torch = torch.arange(5, device='cuda')
>>> np.from_dlpack(x_torch)
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
RuntimeError: Unsupported device in DLTensor.
但是,如果两个库都支持数据缓冲区所在的设备,则可以使用__dlpack__协议(例如 PyTorch 和 CuPy):
>>> x_torch = torch.arange(5, device='cuda')
>>> x_cupy = cupy.from_dlpack(x_torch)
同样,可以将 NumPy 数组转换为 PyTorch 张量:
>>> x_np = np.arange(5)
>>> x_torch = torch.from_dlpack(x_np)
只读数组无法导出:
>>> x_np = np.arange(5)
>>> x_np.flags.writeable = False
>>> torch.from_dlpack(x_np)
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
File ".../site-packages/torch/utils/dlpack.py", line 63, in from_dlpack
dlpack = ext_tensor.__dlpack__()
TypeError: NumPy currently only supports dlpack for writeable arrays
进一步阅读
-
数组接口协议
-
编写自定义数组容器
-
特殊属性和方法(关于
__array_ufunc__和__array_function__协议的详细信息) -
子类化 ndarray(关于
__array_wrap__和__array_finalize__方法的详细信息) -
ndarray 子类型化的特定特性(关于
__array_finalize__、__array_wrap__和__array_priority__实现的更多详细信息)
附加文件
术语表
(n,)
括号中跟着逗号的数字表示一个具有一个元素的元组。尾随逗号将一个元素元组与括号n区分开。
-1
-
在维度入口中,指示 NumPy 选择长度,以保持数组元素总数不变。
>>> np.arange(12).reshape(4, -1).shape (4, 3) -
在索引中,任何负值表示从右边进行索引。
…
一个省略号。
-
当索引数组时,缺失的轴简称为全切片。
>>> a = np.arange(24).reshape(2,3,4)>>> a[...].shape (2, 3, 4)>>> a[...,0].shape (2, 3)>>> a[0,...].shape (3, 4)>>> a[0,...,0].shape (3,)它最多可以使用一次;
a[...,0,...]会引发一个IndexError。 -
在打印输出中,NumPy 用
...替代大数组的中间元素。要查看整个数组,使用numpy.printoptions
:
Python 的切片操作符。在 ndarrays 中,切片可以应用于每个轴:
>>> a = np.arange(24).reshape(2,3,4)
>>> a
array([[[ 0, 1, 2, 3],
[ 4, 5, 6, 7],
[ 8, 9, 10, 11]],
[[12, 13, 14, 15],
[16, 17, 18, 19],
[20, 21, 22, 23]]])
>>> a[1:,-2:,:-1]
array([[[16, 17, 18],
[20, 21, 22]]])
尾部切片可以省略:
>>> a[1] == a[1,:,:]
array([[ True, True, True, True],
[ True, True, True, True],
[ True, True, True, True]])
与 Python 不同,NumPy 中切片创建一个视图而不是副本。
详见组合高级和基本索引。
<
在 dtype 声明中,表示数据为小端(右边是大括号)。
>>> dt = np.dtype('<f') # little-endian single-precision float
在 dtype 声明中,表示数据为大端(左边是大括号)。
>>> dt = np.dtype('>H') # big-endian unsigned short
高级索引
而不是使用标量或切片作为索引,一个轴可以用数组作为索引,提供精细选择。这被称为高级索引或“花式索引”。
沿轴
数组a的操作沿轴 n的行为就好像它的参数是数组a的切片数组,每个切片在轴n上具有连续索引。
例如,如果a是一个 3 x N数组,沿轴 0 的操作表现得好像它的参数是包含每行切片的数组:
>>> np.array((a[0,:], a[1,:], a[2,:]))
具体起见,我们可以选择操作为数组反转函数numpy.flip,它接受一个axis参数。我们构造一个 3 x 4 数组a:
>>> a = np.arange(12).reshape(3,4)
>>> a
array([[ 0, 1, 2, 3],
[ 4, 5, 6, 7],
[ 8, 9, 10, 11]])
沿轴 0(行轴)翻转得到
>>> np.flip(a,axis=0)
array([[ 8, 9, 10, 11],
[ 4, 5, 6, 7],
[ 0, 1, 2, 3]])
回想沿轴的定义,沿轴 0 翻转是将其参数视为
>>> np.array((a[0,:], a[1,:], a[2,:]))
array([[ 0, 1, 2, 3],
[ 4, 5, 6, 7],
[ 8, 9, 10, 11]])
而np.flip(a,axis=0)的结果是翻转切片:
>>> np.array((a[2,:],a[1,:],a[0,:]))
array([[ 8, 9, 10, 11],
[ 4, 5, 6, 7],
[ 0, 1, 2, 3]])
数组
在 NumPy 文档中与 ndarray 同义使用。
array_like
任何可以解释为 ndarray 的标量或序列。除了 ndarrays 和标量,此类别还包括列表(可能嵌套并具有不同的元素类型)和元组。由 numpy.array 接受的任何参数都是 array_like。
>>> a = np.array([[1, 2.0], [0, 0], (1+1j, 3.)])
>>> a
array([[1.+0.j, 2.+0.j],
[0.+0.j, 0.+0.j],
[1.+1.j, 3.+0.j]])
数组标量
数组标量是类型/类 float32,float64 等的实例。为了处理操作数的统一性,NumPy 将标量视为零维数组。相比之下,零维数组是包含精确一个值的 ndarray 实例。
轴
数组维度的另一个术语。轴从左到右编号;轴 0 是形状元组中的第一个元素。
在二维矢量中,轴 0 的元素是行,轴 1 的元素是列。
在更高的维度中,情况就不一样了。NumPy 将更高维度的矢量打印为行列建造块的复制,就像这个三维矢量一样:
>>> a = np.arange(12).reshape(2,2,3)
>>> a
array([[[ 0, 1, 2],
[ 3, 4, 5]],
[[ 6, 7, 8],
[ 9, 10, 11]]])
a被描述为一个其元素为 2x3 矢量的两元素数组。从这个角度来看,行和列分别是任何形状中的最终两个轴。
这个规则可以帮助你预测矢量将如何打印,反过来也可以帮助你找到任何打印元素的索引。例如,在这个例子中,8 的最后两个值的索引必须是 0 和 2。由于 8 出现在两个 2x3 中的第二个中,第一个索引必须是 1:
>>> a[1,0,2]
8
在打印矢量时,计算维度的一个方便方法是在开括号后计数[符号。这在区分例如(1,2,3)形状和(2,3)形状时非常有用:
>>> a = np.arange(6).reshape(2,3)
>>> a.ndim
2
>>> a
array([[0, 1, 2],
[3, 4, 5]])
>>> a = np.arange(6).reshape(1,2,3)
>>> a.ndim
3
>>> a
array([[[0, 1, 2],
[3, 4, 5]]])
.base
如果一个数组没有拥有它的内存,那么它的基础属性会返回数组正在引用的对象的内存。该对象可能正在引用另一个对象的内存,因此拥有对象可能是a.base.base.base...。一些作家错误地声称测试base决定数组是否是视图。有关正确的方法,请参阅numpy.shares_memory。
大端
请参见字节序。
BLAS
广播
广播是 NumPy 处理不同大小的 ndarray 的能力,就好像它们都是相同大小一样。
它允许优雅的做-我-知道什么的行为,在这种情况下,将标量添加到向量会将标量值添加到每个元素。
>>> a = np.arange(3)
>>> a
array([0, 1, 2])
>>> a + [3, 3, 3]
array([3, 4, 5])
>>> a + 3
array([3, 4, 5])
通常,向量操作数必须全部具有相同的大小,因为 NumPy 逐元素工作——例如,c = a * b是
c[0,0,0] = a[0,0,0] * b[0,0,0]
c[0,0,1] = a[0,0,1] * b[0,0,1]
...
但在某些有用的情况下,NumPy 可以沿着“缺失”的轴或“太短”的维度复制数据,使形状匹配。复制不会占用内存或时间。详情请参见广播。
C 顺序
与行主导相同。
列主导
查看行优先和列优先顺序。
连续的
如果数组是连续的,则:
-
它占据了一块连续的内存块,以及
-
具有更高索引的数组元素占据更高地址(即,没有步长为负)。
有两种类型的适当连续的 NumPy 数组:
-
Fortran 连续数组指的是以列方式存储的数据,即存储在内存中的数据索引从最低维开始;
-
C 连续,或简单连续的数组,指的是以行方式存储的数据,即存储在内存中的数据索引从最高维开始。
对于一维数组,这些概念是相同的。
例如,2x2 数组A如果其元素按以下顺序存储在内存中,则为 Fortran 连续:
A[0,0] A[1,0] A[0,1] A[1,1]
且如果顺序如下,则为 C 连续:
A[0,0] A[0,1] A[1,0] A[1,1]
要测试数组是否为 C 连续,请使用 NumPy 数组的.flags.c_contiguous属性。要测试 Fortran 连续性,请使用.flags.f_contiguous属性。
拷贝
查看视图。
维度
查看轴。
数据类型
描述 ndarray 中(类型相同的)元素的数据类型。它可以更改以重新解释数组内容。详情请参见数据类型对象(dtype)。
精细索引
高级索引的另一个术语。
字段
在结构化数据类型中,每个子类型称为字段。字段具有名称(字符串)、类型(任何有效的 dtype)和可选的标题。请参见数据类型对象(dtype)。
Fortran 顺序
与列主导相同。
展平
查看拉伸。
同质的
同质数组的所有元素具有相同类型。与 Python 列表相反,ndarrays 是同质的。类型可能很复杂,如结构化数组,但所有元素都具有该类型。
NumPy 的对象数组,其中包含指向 Python 对象的引用,起到异构数组的作用。
数据项大小
dtype 元素的字节大小。
小端
查看字节顺序。
掩码
用于选��仅对某些元素进行操作的布尔数组:
>>> x = np.arange(5)
>>> x
array([0, 1, 2, 3, 4])
>>> mask = (x > 2)
>>> mask
array([False, False, False, True, True])
>>> x[mask] = -1
>>> x
array([ 0, 1, 2, -1, -1])
蒙版数组
坏的或缺失的数据可以通过将其放入蒙版数组中,该数组具有指示无效条目的内部布尔数组来干净地忽略。对于带有蒙版数组的操作会忽略这些条目。
>>> a = np.ma.masked_array([np.nan, 2, np.nan], [True, False, True])
>>> a
masked_array(data=[--, 2.0, --],
mask=[ True, False, True],
fill_value=1e+20)
>>> a + [1, 2, 3]
masked_array(data=[--, 4.0, --],
mask=[ True, False, True],
fill_value=1e+20)
详情请参见蒙版数组。
矩阵
NumPy 的二维矩阵类不应再使用;请使用常规 ndarrays。
ndarray
NumPy 的基本结构。
对象数组
一个其数据类型为object的数组;即,它包含对 Python 对象的引用。对数组进行索引解引用 Python 对象,因此与其他 ndarrays 不同,对象数组具有能够保存异构对象的能力。
ravel
numpy.ravel 和 numpy.flatten 都会将 ndarray 展平。如果可能,ravel会返回视图;flatten总是返回副本。
展平将多维数组折叠为单个维度;如何完成此操作的详细信息(例如,a[n+1]应该是下一行还是下一列)是参数。
记录数组
允许以属性样式(a.field)访问的一个结构化数组,除了a['field']。详情请参见 numpy.recarray.
行主序
参见行主序和列主序。NumPy 默认以行主序创建数组。
标量
在 NumPy 中,通常是数组标量的同义词。
形状
显示 ndarray 每个维度的长度的元组。元组本身的长度即为维度的数量(numpy.ndim)。元组元素的乘积即为数组中的元素数量。详情请参见 numpy.ndarray.shape。
步幅
物理内存是一维的;步幅提供了一种将给定索引映射到内存地址的机制。对于 N 维数组,其strides属性是一个 N 元素元组;从索引i向轴n上的索引i+1前进意味着在地址上添加a.strides[n]个字节。
步幅会自动从数组的 dtype 和形状中计算,但也可以直接使用 as_strided 指定。
详情请参见 numpy.ndarray.strides。
要了解步进是如何支撑 NumPy 视图的强大功能,请参见NumPy 数组:高效数值计算的结构。
结构化数组
其 dtype 为结构化数据类型的数组。
结构化数据类型
用户可以创建包含其他数组和数据类型的任意复杂的 dtype,这些复合 dtype 被称为结构化数据类型。
子数组
嵌套在结构化数据类型中的数组,如此处的b:
>>> dt = np.dtype([('a', np.int32), ('b', np.float32, (3,))])
>>> np.zeros(3, dtype=dt)
array([(0, [0., 0., 0.]), (0, [0., 0., 0.]), (0, [0., 0., 0.])],
dtype=[('a', '<i4'), ('b', '<f4', (3,))])
子数组数据类型
表现得像一个 ndarray 的结构化数据类型的元素。
标题
结构化数据类型中字段名称的别名。
类型
在 NumPy 中,通常是 dtype 的同义词。对于更一般的 Python 含义,请参见此处。
ufunc
NumPy 的快速逐元素计算(向量化)可以选择应用哪个函数。该函数的通用术语是ufunc,缩写为universal function。NumPy 例程具有内置的 ufunc,但用户也可以编写自己的。
向量化
NumPy 把数组处理交给了 C 语言,在那里循环和计算比在 Python 中快得多。为了利用这一点,使用 NumPy 的程序员取消了 Python 循环,而是使用数组对数组操作。向量化 既可以指 C 的卸载,也可以指结构化 NumPy 代码以利用它。
视图
不触及底层数据,NumPy 可使一个数组看起来改变其数据类型和形状。
以此方式创建的数组是一个视图,而且 NumPy 经常利用使用视图而不是创建新数组来获得性能优势。
潜在的缺点是对视图的写入也可能改变原始数组。如果这是一个问题,NumPy 需要创建一个物理上不同的数组 - 一个copy.
一些 NumPy 例程总是返回视图,一些总是返回副本,有些可能返回其中之一,对于一些情况可以指定选择。管理视图和副本的责任落在程序员身上。numpy.shares_memory 可以检查b是否为a的视图,但精确答案并非总是可行,就像文档页面所解释的那样。
>>> x = np.arange(5)
>>> x
array([0, 1, 2, 3, 4])
>>> y = x[::2]
>>> y
array([0, 2, 4])
>>> x[0] = 3 # changing x changes y as well, since y is a view on x
>>> y
array([3, 2, 4])
发布说明
-
1.26.0
-
新功能
-
numpy.array_api中的数组 API v2022.12 支持 -
支持更新的加速 BLAS/LAPACK 库
-
f2py的meson后端支持 -
f2py的bind(c)支持
-
-
改进
f2py的iso_c_binding支持
-
构建系统变更
-
NumPy 特定的构建自定义
-
构建依赖项
-
故障排除
-
-
贡献者
-
已合并的拉取请求
-
-
1.25.2
-
贡献者
-
已合并的拉取请求
-
-
1.25.1
-
贡献者
-
已合并的拉取请求
-
-
1.25.0
-
弃用内容
-
过期弃用
-
兼容性说明
-
当
mode=wrap时,np.pad使用严格的原始数据倍数进行填充 -
移除 Cython 中的
long_t和ulong_t -
针对
ufunc的axes参数错误消息和类型已更改 -
如果使用
where,则支持定义__array_ufunc__的类数组可以覆盖ufunc -
默认情况下,使用 NumPy C API 进行编译现在具有向后兼容性
-
-
新功能
-
np.einsum现在接受具有object数据类型的数组 -
增加对原位矩阵乘法的支持
-
新增
NPY_ENABLE_CPU_FEATURES环境变量 -
NumPy 现在有一个
np.exceptions命名空间 -
np.linalg函数返回 NamedTuples -
np.char中的字符串函数与 NEP 42 自定义 dtype 兼容 -
字符串 dtype 实例可以从字符串抽象 dtype 类创建
-
富士通 C/C++ 编译器现在受支持
-
现在支持 SSL2
-
-
改进
-
NDArrayOperatorsMixin指定它没有__slots__ -
修复复数零点的幂
-
新的
DTypePromotionError -
np.show_config 使用来自 Meson 的信息
-
修复了当以参数 prepend/append 调用时,
np.ma.diff不保留掩码的问题。 -
在 Cython 中修复了 NumPy C-API 的错误处理
-
直接生成随机数生成器的能力
-
numpy.logspace现在支持非标量base参数 -
np.ma.dot()现在支持非 2D 数组 -
在 repr 中明确显示 .npz 文件的键
-
NumPy 现在在
np.dtypes中公开了 DType 类 -
在保存为 .npy 或 .npz 文件之前删除 dtype 元数据
-
numpy.lib.recfunctions.structured_to_unstructured在更多情况下返回视图 -
有符号和无符号整数始终正确比较
-
-
性能改进和更改
-
在启用 AVX-512 的处理器上,
np.argsort更快了 -
在启用 AVX-512 的处理器上,
np.sort更快了 -
__array_function__机制的速度提升](release/1.25.0-notes.html#array-function-machinery-is-now-much-faster) -
ufunc.at的速度可以提升很多](release/1.25.0-notes.html#ufunc-at-can-be-much-faster) -
NpzFile上的成员测试更快](release/1.25.0-notes.html#faster-membership-test-on-npzfile)
-
-
变更](release/1.25.0-notes.html#changes)
-
np.r_[]和np.c_[]的某些标量值](release/1.25.0-notes.html#np-r-and-np-c-with-certain-scalar-values) -
大多数 NumPy 函数被包装为可调用的 C 函数](release/1.25.0-notes.html#most-numpy-functions-are-wrapped-into-a-c-callable)
-
C++ 标准库使用](release/1.25.0-notes.html#c-standard-library-usage)
-
-
-
1.24.3
-
贡献者](release/1.24.3-notes.html#contributors)
-
合并的拉取请求](release/1.24.3-notes.html#pull-requests-merged)
-
-
1.24.2
-
贡献者](release/1.24.2-notes.html#contributors)
-
合并的拉取请求](release/1.24.2-notes.html#pull-requests-merged)
-
-
1.24.1
-
贡献者](release/1.24.1-notes.html#contributors)
-
合并的拉取请求](release/1.24.1-notes.html#pull-requests-merged)
-
-
1.24.0
-
弃用信息
-
弃用
fastCopyAndTranspose和PyArray_CopyAndTranspose](release/1.24.0-notes.html#deprecate-fastcopyandtranspose-and-pyarray-copyandtranspose) -
Python 整数的越界转换
-
弃用
msort](release/1.24.0-notes.html#deprecate-msort) -
np.str0和类似对象现在弃用](release/1.24.0-notes.html#np-str0-and-similar-are-now-deprecated)
-
-
弃用过期的内容](release/1.24.0-notes.html#expired-deprecations)
-
兼容性说明](release/1.24.0-notes.html#compatibility-notes)
-
array.fill(scalar)的行为可能略有不同](release/1.24.0-notes.html#array-fill-scalar-may-behave-slightly-different) -
子数组到对象的转换现在会进行拷贝](release/1.24.0-notes.html#subarray-to-object-cast-now-copies)
-
返回的数组将尊重 dtype 参数对象的唯一性](release/1.24.0-notes.html#returned-arrays-respect-uniqueness-of-dtype-kwarg-objects)
-
BufferError引发 DLPack 导出错误 -
不再在 GCC-6 上进行 NumPy 构建的测试](release/1.24.0-notes.html#numpy-builds-are-no-longer-tested-on-gcc-6)
-
-
新特性](release/1.24.0-notes.html#new-features)
-
多项式类中添加了新的
symbol属性](release/1.24.0-notes.html#new-attribute-symbol-added-to-polynomial-classes) -
Fortran
character字符串的 F2PY 支持](release/1.24.0-notes.html#f2py-support-for-fortran-character-strings) -
新函数
np.show_runtime](release/1.24.0-notes.html#new-function-np-show-runtime) -
testing.assert_array_equal的strict选项](release/1.24.0-notes.html#strict-option-for-testing-assert-array-equal) -
添加到
np.unique的新参数equal_nan -
numpy.stack的casting和dtype关键字参数 -
numpy.vstack的casting和dtype关键字参数 -
numpy.hstack的casting和dtype关键字参数 -
底层的单实例 RandomState 的比特生成器可以更改
-
np.void现在有一个dtype参数
-
-
改进
-
F2PY 改进
-
IBM zSystems Vector Extension Facility (SIMD)
-
NumPy 现在在转换中产生浮点错误
-
F2PY 支持 value 属性
-
为第三方 BitGenerators 添加了 pickle 支持
-
arange()现在明确在 dtype 为 str 时失败 -
numpy.typing协议现在可以在运行时检查
-
-
性能改进和变更
-
为整数数组提供
np.isin和np.in1d的更快版本 -
更快的比较运算符
-
-
变更
-
更好的整数除法溢出报告
-
masked_invalid现在就地修改掩码 -
nditer/NpyIter允许为所有操作数进行分配
-
-
-
1.23.5
-
贡献者
-
合并的拉取请求
-
-
1.23.4
-
贡献者
-
合并的拉取请求
-
-
1.23.3
-
贡献者
-
合并的拉取请求
-
-
1.23.2
-
贡献者
-
合并的拉取请求
-
-
1.23.1
-
贡献者
-
合并的拉取请求
-
-
1.23.0
-
新函数
-
弃用信息
-
过期的弃用项
-
新特性
-
crackfortran 现在支持运算符和赋值重载
-
f2py 支持从派生类型语句中读取访问类型属性
-
genfromtxt新增参数ndmin -
np.loadtxt现在支持引号字符和单个转换函数 -
改变到不同尺寸的 dtype 现在只需要最后一个轴连续性
-
F2PY 的确定性输出文件
-
average的keepdims参数 -
np.unique新增参数equal_nan
-
-
兼容性说明
-
1 维
np.linalg.norm现在保留了浮点输入类型,即使对于标量结果 -
对结构化(void) dtype 提升和比较的更改
-
NPY_RELAXED_STRIDES_CHECKING已被移除 -
[
np.loadtxt已经接收到一些更改
-
-
改进
-
ndarray.__array_finalize__现在可调用 -
添加对 VSX4/Power10 的支持
-
np.fromiter现在接受对象和子数组 -
Math C 库特性检测现在使用正确的签名
-
np.kron现在保留子类信息
-
-
性能改进和更改
-
更快的
np.loadtxt -
更快的约简运算符
-
更快的
np.where -
NumPy 标量上的更快操作
-
更快的
np.kron
-
-
-
1.22.4
-
贡献者
-
已合并的拉取请求
-
-
1.22.3
-
贡献者
-
已合并的拉取请求
-
-
1.22.2
-
贡献者
-
已合并的拉取请求
-
-
1.22.1
-
贡献者
-
已合并的拉取请求
-
-
1.22.0
-
过时的弃用
-
已移除废弃的数值风格 dtype 字符串
-
在 npyio 中
loads,ndfromtxt和mafromtxt的过时弃用已移除
-
-
弃用
-
在 mrecords 中使用分隔符而不是作为 kwarg 的 delimitor
-
将布尔
kth值传递给(arg-)partition 已被弃用 -
np.MachAr类已被弃用
-
-
兼容性注意事项
-
Distutils 对 clang 强制使用严格的浮点模型
-
已删除复数类型的 floor division 支持
-
numpy.vectorize函数现在产生与基础函数相同的输出类 -
不再支持 Python 3.7
-
复杂数据类型的 str/repr 现在在标点符号后包含空格
-
在
PCG64DSXM和PCG64中纠正了advance -
生成 32 位浮点随机变量方式的改变
-
-
C API 变更
-
内部屏蔽循环不再可定制化
-
未来 DType 和 UFunc API 的实验性曝光
-
-
新特性
-
NEP 49 配置分配器
-
实施 NEP 47(采用数组 API 标准)
-
可以从注释块生成 C/C++ API 参考文档
-
通过 mypy 插件分配平台特定的
c_intp精度 -
添加 NEP 47 兼容的 dlpack 支持
-
keepdims可选参数添加到numpy.argmin,numpy.argmax -
bit_count用于计算整数中 1 位的数量 -
ndim和axis属性已添加到numpy.AxisError -
windows/arm64目标的初步支持 -
增加对龙芯的支持
-
添加了
.clang-format文件 -
is_integer现在适用于numpy.floating和numpy.integer -
Fortran 维度规范的符号解析器
-
ndarray,dtype和number现在可以在运行时进行下标索引
-
-
改进
-
ctypeslib.load_library现在可以接受任何类路径对象 -
给
finfo添加smallest_normal和smallest_subnormal属性 -
numpy.linalg.qr接受堆叠矩阵作为输入 -
numpy.fromregex现在接受os.PathLike的实现 -
为
quantile和percentile添加新方法 -
向
nan<x>函数添加了缺失参数 -
对主要的 NumPy 命名空间进行注释
-
使用 AVX-512 对 umath 模块进行向量化
-
OpenBLAS v0.3.18
-
-
-
1.21.6
-
1.21.5
-
贡献者
-
已合并的拉取请求
-
-
1.21.4
-
贡献者
-
已合并的拉取请求
-
-
1.21.3
-
贡献者
-
已合并的拉取请求
-
-
1.21.2
-
贡献者
-
已合并的拉取请求
-
-
1.21.1
-
贡献者
-
已合并的拉取请求
-
-
1.21.0
-
新函数
- 添加
PCG64DXSMBitGenerator
- 添加
-
过期的弃用项
-
已弃用项
-
.dtype属性必须返回dtype -
numpy.convolve和numpy.correlate的不精确匹配已弃用 -
np.typeDict已正式弃用 -
在类似数组创建时会引发异常
-
已弃用四个
ndarray.ctypes方法
-
-
过期的弃用项
- 移除已弃用的
PolyBase和未使用的PolyError和PolyDomainError
- 移除已弃用的
-
兼容性说明
-
通用函数的错误类型更改
-
__array_ufunc__参数验证 -
__array_ufunc__和额外的位置参数 -
在
Generator.uniform中验证输入数值 -
/usr/include从默认包含路径中移除 -
对具有
dtype=...的比较的更改 -
在 ufuncs 中的
dtype和signature参数的更改 -
Ufunc
signature=...和dtype=泛化以及casting -
Distutils 对 clang 强制使用严格浮点模型
-
-
C API 改变
- 使用
ufunc->type_resolver和 “type tuple”
- 使用
-
新功能
-
为处理特定平台
numpy.number精度添加了一个 mypy 插件 -
让 mypy 插件管理扩展精度
numpy.number子类 -
用于打印浮点数值的新
min_digits参数 -
f2py 现在可以识别 Fortran 抽象接口块
-
通过环境变量配置 BLAS 和 LAPACK
-
为
ndarray添加了一个运行时可订阅的别名
-
-
改进
-
numpy.unwrap的任意period选项 -
np.unique现在返回单个NaN -
Generator.rayleigh和Generator.geometric性能改进 -
改进了占位符注解
-
-
性能改进
-
NumPy 数组整数除法性能改进
-
优化
np.save和np.load在小数组上的性能
-
-
更改
-
numpy.piecewise的输出类现在与输入类匹配 -
启用 Accelerate Framework
-
-
-
1.20.3
-
贡献者
-
合并的拉取请求
-
-
1.20.2
-
贡献者
-
合并的拉取请求
-
-
1.20.1
-
亮点
-
贡献者
-
合并的拉取请求
-
-
1.20.0
-
新函数
-
random.Generator类有一个新的permuted函数。 -
sliding_window_view为 numpy 数组提供了滑动窗口视图(release/1.20.0-notes.html#sliding-window-view-provides-a-sliding-window-view-for-numpy-arrays) -
numpy.broadcast_shapes是一���新的用户可见函数(release/1.20.0-notes.html#numpy-broadcast-shapes-is-a-new-user-facing-function)
-
-
弃用(release/1.20.0-notes.html#deprecations)
-
弃用使用
np.int等内置类型的别名(release/1.20.0-notes.html#using-the-aliases-of-builtin-types-like-np-int-is-deprecated) -
将
shape=None传递给具有非可选形状参数的函数已被弃用(release/1.20.0-notes.html#passing-shape-none-to-functions-with-a-non-optional-shape-argument-is-deprecated) -
索引错误即使索引结果为空也会报告(release/1.20.0-notes.html#indexing-errors-will-be-reported-even-when-index-result-is-empty)
-
mode和searchside的不精确匹配已被弃用(release/1.20.0-notes.html#inexact-matches-for-mode-and-searchside-are-deprecated) -
numpy.dual 的弃用(release/1.20.0-notes.html#deprecation-of-numpy-dual)
-
outer和ufunc.outer对矩阵已弃用(release/1.20.0-notes.html#outer-and-ufunc-outer-deprecated-for-matrix) -
进一步弃用数字样式类型(release/1.20.0-notes.html#further-numeric-style-types-deprecated)
-
ndindex的ndincr方法已被弃用(release/1.20.0-notes.html#the-ndincr-method-of-ndindex-is-deprecated) -
未定义
__len__和__getitem__的 ArrayLike 对象(release/1.20.0-notes.html#arraylike-objects-which-do-not-define-len-and-getitem)
-
-
未来更改(release/1.20.0-notes.html#future-changes)
- 数组不能使用子数组 dtypes(release/1.20.0-notes.html#arrays-cannot-be-using-subarray-dtypes)
-
过时的废弃
- 已移除财务函数。
-
兼容性注意事项
-
isinstance(dtype, np.dtype)而不是type(dtype) is not np.dtype。 -
在
axis=None的情况下使用相同种类转换融合。 -
赋值给数组时,NumPy 标量会被转换。
-
当混合字符串和其他类型时,数组强制转换会发生变化。
-
数组强制转换重构
-
写入
numpy.broadcast_arrays的结果将导出只读缓冲区。 -
数字样式类型名称已从类型词典中删除。
-
operator.concat函数现在对数组参数引发 TypeError。 -
从 ABCPolyBase 中删除了
nickname属性。 -
float->timedelta和uint64->timedelta提升将引发 TypeError。 -
numpy.genfromtxt现在正确解包结构化数组。 -
mgrid、r_等对非默认精度输入一直返回正确输出。 -
形状不匹配的布尔数组索引现在会正常地引发
IndexError。 -
转换错误中断迭代。
-
f2py 生成的代码可能返回 Unicode 而不是字节字符串。
-
__array_interface__["data"]元组的第一个元素必须是整数。 -
poly1d尊重所有零参数的数据类型。 -
swig 的 numpy.i 文件仅适用于 Python 3。
-
在
np.array中发现空数据类型。
-
-
C API 变化
-
PyArray_DescrCheck宏被修改 -
np.ndarray和np.void_的大小发生了变化
-
-
新特性
-
numpy.all和numpy.any函数的where关键字参数 -
numpy函数mean、std、var的where关键字参数 -
numpy.fft函数的norm=backward、forward关键字选项 -
NumPy 现在是有类型的
-
运行时可访问
numpy.typing -
为 f2py 生成的模块添加新的
__f2py_numpy_version__属性。 -
通过 runtests.py 可以运行
mypy测试 -
否定用户定义的 BLAS/LAPACK 检测顺序
-
允许通过 asv build 传递优化参数
-
现在支持 NVIDIA HPC SDK nvfortran 编译器
-
cov和corrcoef的dtype选项
-
-
改进
-
改进多项式的字符串表示(
__str__) -
将 Accelerate 库从 LAPACK 库候选中移除
-
包含多行对象的对象数组的
repr更易读 -
concatenate函数支持提供输出的数据类型 -
f2py 回调函数线程安全
-
numpy.core.records.fromfile现在支持类文件对象 -
在 AIX 上添加对 RPATH 的支持到 distutils
-
使用命令行参数指定的 f90 编译器
-
为 Cython 3.0 及以上版本添加 NumPy 声明
-
使窗口函数完全对称
-
-
性能改进和更改
- 启用多平台 SIMD 编译器优化
-
更改
-
更改
divmod(1., 0.)和相关函数的行为 -
np.linspace在整数上使用 floor](release/1.20.0-notes.html#np-linspace-on-integers-now-uses-floor)
-
-
-
1.19.5
-
贡献者
-
合并的拉取请求
-
-
1.19.4
-
贡献者
-
合并的拉取请求
-
-
1.19.3
-
贡献者
-
合并的拉取请求
-
-
1.19.2
-
改进
- 为 Cython 3.0 及以上版本添加 NumPy 声明
-
贡献者
-
合并的拉取请求
-
-
1.19.1
-
贡献者
-
合并的拉取请求
-
-
1.19.0
-
亮点
-
已过时退役
-
numpy.insert和numpy.delete不再可以在 0 维数组上通过轴传递](release/1.19.0-notes.html#numpy-insert-and-numpy-delete-can-no-longer-be-passed-an-axis-on-0d-arrays) -
numpy.delete不再忽略超出范围的索引](release/1.19.0-notes.html#numpy-delete-no-longer-ignores-out-of-bounds-indices) -
numpy.insert和numpy.delete不再接受非整数索引](release/1.19.0-notes.html#numpy-insert-and-numpy-delete-no-longer-accept-non-integral-indices) -
numpy.delete不再将布尔索引强制转换为整数](release/1.19.0-notes.html#numpy-delete-no-longer-casts-boolean-indices-to-integers)
-
-
兼容性说明
-
从
numpy.random.Generator.dirichlet更改随机变量流 -
PyArray_ConvertToCommonType中的标量提升 -
Fasttake 和 fastputmask slots 被废弃并设置为 NULL
-
np.ediff1d在to_end和to_begin上的类型转换行为 -
将空数组对象转换为 NumPy 数组
-
移除
multiarray.int_asbuffer -
移除了
numpy.distutils.compat -
issubdtype不再将float解释为np.floating -
更改标量上
round的输出以与 Python 一致 -
numpy.ndarray构造函数不再将strides=()解释为strides=None -
C 级别的字符串到日期时间转换已更改
-
使用小种子的
SeedSequence不再与生成冲突
-
-
废弃内容
-
废弃对不规整输入的自动
dtype=object -
传递
shape=0到numpy.rec工厂函数已被废弃 -
废弃可能未使用的 C-API 函数
-
转换某些类型到 dtypes 已废弃
-
废弃
np.complexfloating标量的round操作 -
numpy.ndarray.tostring()已被废弃,推荐使用tobytes()
-
-
C API 变更
-
API 函数中对
const维度的更好支持 -
UFunc 内部循环增加 const 修饰符
-
-
新特性
-
numpy.frompyfunc现在接受一个 identity 参数 -
np.str_标量现在支持缓冲区协议 -
numpy.copy的subok选项 -
numpy.linalg.multi_dot现在接受out参数 -
numpy.count_nonzero的keepdims参数 -
numpy.array_equal的equal_nan参数
-
-
改进
-
改进 CPU 特性的检测
-
在回退的 lapack_lite 中,64 位平台上使用 64 位整数大小
-
当输入为
np.float64时,使用 AVX512 内部实现np.exp -
禁用 madvise hugepages 的能力
-
numpy.einsum在子脚本列表中接受 NumPyint64类型 -
np.logaddexp2.identity更改为-inf
-
-
变更
-
移除了对
__array__的额外参数处理 -
numpy.random._bit_generator移动到numpy.random.bit_generator -
通过
pxd文件提供对随机分布的 Cython 访问 -
修复了
numpy.random.multivariate_normal中eigh和cholesky方法 -
修复了
MT19937.jumped中跳转的实现
-
-
-
1.18.5
-
贡献者
-
合并的拉取请求
-
-
1.18.4
-
贡献者
-
合并的拉取请求
-
-
1.18.3
-
亮点
-
贡献者
-
合并的拉取请求
-
-
1.18.2
-
贡献者
-
合并的拉取请求
-
-
1.18.1
-
贡献者
-
合并的拉取请求
-
-
1.18.0
-
亮点
-
新函数
- 在
numpy.random中添加多元超几何分布
- 在
-
废弃
-
np.fromfile和np.fromstring将在错误数据上报错 -
在
ma.fill_value中废弃非标量数组作为填充值 -
废弃
PyArray_As1D,PyArray_As2D -
废弃了
np.alen -
废弃了金融函数
-
numpy.ma.mask_cols和numpy.ma.mask_row的axis参数已废弃
-
-
弃用的废止
-
兼容性说明
-
numpy.lib.recfunctions.drop_fields不再返回 None -
如果
numpy.argmin/argmax/min/max在数组中存在,则返回NaT -
现在
np.can_cast(np.uint64, np.timedelta64, casting='safe')为False -
从
numpy.random.Generator.integers中更改随机变量流 -
为
datetime64和timedelta64添加更多的 ufunc 循环 -
numpy.random中的模块已移动
-
-
C API 更改
PyDataType_ISUNSIZED(descr)对于结构化数据类型现在返回 False
-
新特性
-
添加我们自己的
*.pxdcython 导入文件 -
现在可以输入一个轴的元组到
expand_dims中 -
支持 64 位 OpenBLAS
-
在 F2PY 中添加
--f2cmap选项
-
-
改进
-
相同大小的不同 C 数值类型具有唯一的名称
-
argwhere在 0 维数组上现在产生一致的结果 -
为
random.permutation和random.shuffle添加axis参数 -
method关键字参数用于np.random.multivariate_normal -
为
numpy.fromstring增加复数支持 -
当
axis不为 None 时,numpy.unique有一致的轴顺序 -
numpy.matmul的布尔输出现在转换为布尔值 -
numpy.random.randint在范围为2**32时产生不正确的值 -
为
numpy.fromfile增加复数支持 -
gcc命名的编译器现在添加std=c99参数](发布/1.18.0-说明.html#std-c99-added-if-compiler-is-named-gcc)
-
-
变更
-
NaT现在排序到数组的末尾 -
在
np.set_printoptions中不正确的threshold会引发TypeError或ValueError -
保存带有元数据的数据类型时发出警告
-
numpy.distutils在 LDFLAGS 和类似情况下的 append 行为发生更改 -
移除未弃用的
numpy.random.entropy -
添加选项以安静地配置构建并用
-Werror构建
-
-
-
1.17.5
-
贡献者
-
已合并的拉取请求
-
-
1.17.4
-
亮点
-
贡献者
-
已合并的拉取请求
-
-
1.17.3
-
亮点
-
兼容性说明
-
贡献者
-
已合并的拉取请求
-
-
1.17.2
-
贡献者
-
已合并的拉取请求
-
-
1.17.1
-
贡献者
-
合并的拉取请求
-
-
1.17.0
-
亮点
-
新函数
-
废弃项
-
numpy.polynomial函数在传递float而非int时会警告 -
弃用
numpy.distutils.exec_command和temp_file_name -
C-API 封装数组的��写标志
-
numpy.nonzero不应该再在 0d 数组上调用 -
写入
numpy.broadcast_arrays的结果会产生警告
-
-
未来的变化
- dtypes 中的形状为 1 的字段在将来的版本中不会被折叠成标量
-
兼容性说明
-
float16次正规化舍入 -
使用 divmod 时的带符号零
-
MaskedArray.mask现在返回掩码的视图,而不是掩码本身 -
不要在
numpy.frombuffer中查找__buffer__属性 -
out在take,choose,put中用于内存重叠时被缓冲 -
加载时拆开解除引用需要显式选择
-
旧 random 模块中随机流的潜在变化
-
i0现在总是返回与输入相同形状的结果 -
can_cast不再假设所有不安全的转换都是允许的 -
ndarray.flags.writeable稍微更频繁地切换到 true
-
-
C API 变化
- 维度或步长输入参数现在通过
npy_intp const*传递
- 维度或步长输入参数现在通过
-
新特性
-
具有可选择的随机数生成器的新可扩展
numpy.random模块 -
libFLAME
-
用户定义的 BLAS 检测顺序
-
用户定义的 LAPACK 检测顺序
-
ufunc.reduce和相关函数现在接受一个where掩码 -
Timsort 和基数排序已替换 mergesort 以实现稳定排序
-
packbits和unpackbits接受一个order关键字 -
unpackbits现在接受一个count参数 -
linalg.svd和linalg.pinv在 Hermitian 输入上可能更快 -
divmod操作现在支持两个timedelta64操作数 -
fromfile现在接受一个offset参数 -
pad的新模式 “empty” -
empty_like和相关函数现在接受一个shape参数 -
浮点数标量实现
as_integer_ratio以匹配内置的 float -
结构化的
dtype对象可以用多个字段名称进行索引 -
.npy文件支持 Unicode 字段名称
-
-
改进
-
数组比较断言包括最大差异
-
用 pocketfft 库替换了基于 fftpack 的
fft模块 -
在
numpy.ctypeslib中对ctypes支持的进一步改进 -
numpy.errstate现在也是一个函数装饰器 -
numpy.exp和numpy.log在 float32 实现上加速 -
改进
numpy.pad的性能 -
numpy.interp更稳健地处理无穷大 -
Pathlib支持fromfile,tofile和ndarray.dump -
对于 bool 和 int 类型的特定化的
isnan,isinf和isfiniteufuncs -
isfinite支持datetime64和timedelta64类型 -
nan_to_num中添加了新的关键字 -
分配过大的数组引起的 MemoryError 错误更加详细
-
floor,ceil和trunc现在尊重内置魔术方法 -
quantile现在可以在Fraction和decimal.Decimal对象上使用 -
matmul中支持对象数组
-
-
变更
-
median和percentile函数族不再对nan发出警告 -
将
timedelta64 % 0行为调整为返回NaT -
NumPy 函数现在始终支持通过
__array_function__进行重写 -
lib.recfunctions.structured_to_unstructured不会压缩单个字段视图 -
clip现在在底层使用 ufunc -
__array_interface__偏移现在按照文档正常工作 -
在
savez函数中将 pickle 协议设置为 3 以强制使用 zip64 标志 -
使用不存在的字段索引结构化数组时引发
KeyError而不是ValueError
-
-
-
1.16.6
-
亮点
-
新功能
- 允许
matmul (*@* operator)与对象数组一起使用。
- 允许
-
兼容性说明
- 修复 bool 类型在 matmul(@操作符)中的回归
-
改进
- 数组比较断言包含最大差异
-
贡献者
-
已合并的拉取请求
-
-
1.16.5
-
贡献者
-
已合并的拉取请求
-
-
1.16.4
-
新的停用功能
- C-API 封装数组的可写标记
-
兼容性注意事项
- 随机流的潜在改动
-
变更
numpy.lib.recfunctions.structured_to_unstructured不会压缩单字段视图
-
贡献者
-
已合并的拉取请求
-
-
1.16.3
-
兼容性注意事项
- 加载时解 pickling 需要显式选择
-
改进
- random.mvnormal中的协方差转换为 double
-
变更
__array_interface__偏移现在按照文档工作
-
-
1.16.2
-
兼容性注意事项
- 使用 divmod 时的有符号零
-
贡献者
-
已合并的拉取请求
-
-
1.16.1
-
贡献者
-
增强
-
兼容性注意事项
-
新特性
timedelta64操作数现在支持 divmod 操作
-
改进
-
np.ctypeslib中ctypes支持的进一步改进 -
数组比较断言包括最大差异(array comparison assertions include maximum differences)
-
-
更改(Changes)
- 调整了
timedelta64 % 0的行为以返回NaT(timedelta64 % 0 behavior adjusted to return NaT)
- 调整了
-
-
1.16.0
-
亮点
-
新函数(New functions)
-
新的弃用特性(New deprecations)
-
过期的弃用特性(Expired deprecations)
-
未来的更改(Future changes)
-
兼容性注意事项(Compatibility notes)
-
Windows 上的 f2py 脚本(f2py script on Windows)
-
NaT 比较(NaT comparisons)
-
complex64/128的对齐方式已更改(complex64/128 alignment has changed) -
nd_grid __len__已移除(nd_grid len removal) -
np.unravel_index现在接受shape关键字参数 -
多字段视图返回视图而不是副本(multi-field views return a view instead of a copy)
-
-
C API 更改(C API changes)
-
新特性(New Features)
-
histogram中添加了综合平方误差(ISE)估计器(integrated squared error (ISE) estimator added to histogram) -
给
np.loadtxt添加了max_rows关键字(max_rows keyword added for np.loadtxt) -
np.timedelta64操作数现在有模运算支持(modulus operator support added for np.timedelta64 operands)
-
-
改进(Improvements)
-
numpy 数组的无副本 pickling(no-copy pickling of numpy arrays)
-
构建独立的 shell(build shell independence)
-
np.polynomial.Polynomial类会在 Jupyter 笔记本中以 LaTeX 渲染(np.polynomial.Polynomial classes render in LaTeX in Jupyter notebooks) -
randint和choice现在适用于空分布(randint and choice now work on empty distributions) -
linalg.lstsq,linalg.qr, 和linalg.svd现在适用于空数组(linalg.lstsq, linalg.qr, and linalg.svd now work with empty arrays) -
错误的
PEP3118格式字符串会抛出更好的错误消息以链式异常处理(Chain exceptions to give better error messages for invalid PEP3118 format strings) -
Einsum 优化路径更新和效率提升(Einsum optimization path updates and efficiency improvements)
-
numpy.angle和numpy.expand_dims现在适用于ndarray子类 -
NPY_NO_DEPRECATED_API编译器警告抑制 -
np.diff添加了 kwargs prepend 和 append -
ARM 支持更新
-
追加到构建标志
-
广义 ufunc 签名现在允许固定大小的维度
-
广义 ufunc 签名现在允许灵活的维度
-
np.clip和clip方法检查内存重叠 -
np.polyfit中cov选项的新值unscaled -
标量数值类型详细的文档字符串
-
__module__属性现在指向公共模块 -
大型分配标记为透明大页适用
-
Alpine Linux(以及其他 musl C 库发行版)支持
-
加快
np.block大型数组的速度 -
加快只读数组的
np.take -
支持类似路径对象的更多功能
-
在缩减过程中 ufunc 身份的行为更好
-
从 ctypes 对象改进的转换
-
一个新的
ndpointer.contents成员 -
matmul现在是一个ufunc -
linspace,logspace和geomspace的起始和停止数组 -
CI 扩展了额外的服务
-
-
更改
-
比较 ufunc 现在会报错而不是返回 NotImplemented
-
positive现在会对非数值数组发出弃用警告 -
NDArrayOperatorsMixin现在实现矩阵乘法 -
np.polyfit中协方差矩阵的缩放方式不同 -
maximum和minimum不再发出警告 -
Umath 和 multiarray C 扩展模块合并为一个单独模块
-
getfield的有效性检查已扩展 -
NumPy 函数现在支持使用
__array_function__进行覆盖 -
基于只读缓冲区的数组不能设置为
writeable
-
-
-
1.15.4
-
兼容性注意事项
-
贡献者
-
已合并的拉取请求
-
-
1.15.3
-
兼容性注意事项
-
贡献者
-
已合并的拉取请求
-
-
1.15.2
-
兼容性注意事项
-
贡献者
-
已合并的拉取请求
-
-
1.15.1
-
兼容性注意事项
-
贡献者
-
已合并的拉取请求
-
-
1.15.0
-
亮点
-
新函数
-
废弃功能
-
未来变更
-
兼容性注意事项
-
编译测试模块重命名并设为私有
-
np.savez返回的NpzFile现在是collections.abc.Mapping -
在某些条件下,必须在上下文管理器中使用
nditer -
Numpy 已转而使用 pytest 而不是 nose 进行测试
-
Numpy 不再使用
__array_interface__向ctypes施加修改 -
np.ma.notmasked_contiguous和np.ma.flatnotmasked_contiguous现在总是返回列表 -
np.squeeze恢复了无法处理axis参数的对象的旧行为 -
非结构化 void 数组的
.item方法现在返回一个字节对象 -
copy.copy和copy.deepcopy不再将masked转换为数组 -
结构化数组的多字段索引仍将返回一个副本](release/1.15.0-notes.html#multifield-indexing-of-structured-arrays-will-still-return-a-copy)
-
-
C API 变更
-
新函数
npy_get_floatstatus_barrier和npy_clear_floatstatus_barrier -
PyArray_GetDTypeTransferFunction更改
-
-
新特性
-
np.gcd和np.lcm函数现针对整数和对象类型 -
支持 iOS 跨平台构建
-
np.intersect1d添加了return_indices关键字 -
np.quantile和np.nanquantile -
构建系统
-
-
改进
-
np.einsum更新 -
np.ufunc.reduce和相关函数现在接受初始值 -
np.flip可以在多个轴上操作 -
histogram和histogramdd函数已移至np.lib.histograms -
在给定显示的 bins 时,
histogram将接受 NaN 值 -
当给定显式的 bin 边界时,
histogram可以处理日期时间类型 (release/1.15.0-notes.html#histogram-works-on-datetime-types-when-explicit-bin-edges-are-given) -
histogram的“auto”估计器更好地处理有限方差 (release/1.15.0-notes.html#histogram-auto-estimator-handles-limited-variance-better) -
histogram和histogramdd返回的边界现在与数据的浮点类型匹配 (release/1.15.0-notes.html#the-edges-returned-by-histogram-and-histogramdd-now-match-the-data-float-type) -
histogramdd允许在一部分轴上给定显式范围 (release/1.15.0-notes.html#histogramdd-allows-explicit-ranges-to-be-given-in-a-subset-of-axes) -
histogramdd和histogram2d的 normed 参数已重命名 (release/1.15.0-notes.html#the-normed-arguments-of-histogramdd-and-histogram2d-have-been-renamed) -
np.r_与 0d 数组一起使用,np.ma.mr_与np.ma.masked一起使用 (release/1.15.0-notes.html#np-r-works-with-0d-arrays-and-np-ma-mr-works-with-np-ma-masked) -
np.ptp接受keepdims参数和扩展的轴元组 (release/1.15.0-notes.html#np-ptp-accepts-a-keepdims-argument-and-extended-axis-tuples) -
MaskedArray.astype现在与ndarray.astype相同 -
在编译时启用 AVX2/AVX512 (release/1.15.0-notes.html#enable-avx2-avx512-at-compile-time)
-
当接收标量或 0d 输入时,
nan_to_num总是返回标量 (release/1.15.0-notes.html#nan-to-num-always-returns-scalars-when-receiving-scalar-or-0d-inputs) -
np.flatnonzero在 numpy 可转换类型上工作 (release/1.15.0-notes.html#np-flatnonzero-works-on-numpy-convertible-types) -
np.interp返回 numpy 标量,而不是内建标量 -
允许在 Python 2 中将 dtype 字段名设置为 Unicode (release/1.15.0-notes.html#allow-dtype-field-names-to-be-unicode-in-python-2)
-
比较 ufuncs 接受
dtype=object,覆盖默认的bool(release/1.15.0-notes.html#comparison-ufuncs-accept-dtype-object-overriding-the-default-bool) -
sort函数接受kind='stable'(release/1.15.0-notes.html#sort-functions-accept-kind-stable) -
对于原地累积不会产生临时副本 (release/1.15.0-notes.html#do-not-make-temporary-copies-for-in-place-accumulation)
-
linalg.matrix_power现在可以处理矩阵堆栈 -
多维数组的
random.permutation性能提高了 (release/1.15.0-notes.html#increased-performance-in-random-permutation-for-multidimensional-arrays) -
广义 ufuncs 现在接受
axes、axis和keepdims参数 (release/1.15.0-notes.html#generalized-ufuncs-now-accept-axes-axis-and-keepdims-arguments) -
在 ppc 系统上,float128 值现在可以正确打印 (release/1.15.0-notes.html#float128-values-now-print-correctly-on-ppc-systems)
-
新的
np.take_along_axis和np.put_along_axis函数
-
-
-
1.14.6
-
贡献者
-
已合并的拉取请求
-
-
1.14.5
-
贡献者
-
已合并的拉取请求
-
-
1.14.4
-
贡献者
-
已合并的拉取请求
-
-
1.14.3
-
贡献者
-
已合并的拉取请求
-
-
1.14.2
-
贡献者
-
已合并的拉取请求
-
-
1.14.1
-
贡献者
-
已合并的拉取请求
-
-
1.14.0
-
亮点
-
新函数
-
已弃用项
-
未来变更
-
兼容性说明
-
遮罩数组视图的遮罩也是一个视图而不是一个拷贝](release/1.14.0-notes.html#the-mask-of-a-masked-array-view-is-also-a-view-rather-than-a-copy)
-
np.ma.masked不再可写 -
np.ma函数生成的fill_value已更改 -
a.flat.__array__()在a不连续时返回不可写的数组 -
np.tensordot现在在收缩为 0 长度的维度时返回零数组 -
numpy.testing重新组织 -
np.asfarray不再接受非数据类型的dtype参数 -
1D
np.linalg.norm保留浮点输入类型,即使对于任意阶数 -
count_nonzero(arr, axis=())现在计数不包括任何轴,而不是所有轴 -
__init__.py文件已添加到测试目录 -
对于非结构化
void数组,现在调用.astype(bool)将在每个元素上调用bool。 -
MaskedArray.squeeze永远不会返回np.ma.masked。 -
将
can_cast的第一个参数从from重命名为from_。 -
当传递错误类型时,
isnat会引发TypeError。 -
当传递错误类型时,
dtype.__getitem__会引发TypeError。 -
现在用户定义类型需要实现
__str__和__repr__。 -
数组打印有许多变化,可通过新的“legacy”打印模式禁用。
-
-
C API 变更。
UPDATEIFCOPY数组的 PyPy 兼容替代方法。
-
新特性。
-
文本 IO 函数的编码参数。
-
外部
nose插件可被numpy.testing.Tester使用。 -
numpy.testing中新增了parametrize装饰器。 -
numpy.polynomial.chebyshev中新增了chebinterpolate函数。 -
Python 3 中支持读取
lzma压缩文本文件。 -
np.setprintoptions和np.array2string中新增了sign选项。 -
np.linalg.matrix_rank中新增了hermitian选项。 -
np.array2string中新增了threshold和edgeitems选项。 -
concatenate和stack新增了out参数。 -
Windows 上支持 PGI flang 编译器。
-
-
改进。
-
在
random.noncentral_f中,分子自由度只需为正数。 -
所有
np.einsum变体都释放了 GIL](release/1.14.0-notes.html#the-gil-is-released-for-all-np-einsum-variations) -
np.einsum 函数在可能的情况下将使用 BLAS 并默认进行优化](release/1.14.0-notes.html#the-np-einsum-function-will-use-blas-when-possible-and-optimize-by-default)
-
f2py现在处理 0 维数组](release/1.14.0-notes.html#f2py-now-handles-arrays-of-dimension-0) -
numpy.distutils支持同时使用 MSVC 和 mingw64-gfortran](release/1.14.0-notes.html#numpy-distutils-supports-using-msvc-and-mingw64-gfortran-together) -
np.linalg.pinv现在可以作用于堆叠矩阵](release/1.14.0-notes.html#np-linalg-pinv-now-works-on-stacked-matrices) -
numpy.save将数据对齐到 64 字节而不是 16 -
现在可以在不使用临时文件的情况下编写 NPZ 文件](release/1.14.0-notes.html#npz-files-now-can-be-written-without-using-temporary-files)
-
空结构化和字符串类型的更好支持](release/1.14.0-notes.html#better-support-for-empty-structured-and-string-types)
-
np.lib.financial中支持decimal.Decimal](release/1.14.0-notes.html#support-for-decimal-decimal-in-np-lib-financial) -
浮点数打印现在使用“dragon4”算法进行最短的十进制表示](release/1.14.0-notes.html#float-printing-now-uses-dragon4-algorithm-for-shortest-decimal-representation)
-
void数据类型元素现在以十六进制表示打印](release/1.14.0-notes.html#void-datatype-elements-are-now-printed-in-hex-notation) -
void数据类型的打印风格现在可以单独定制](release/1.14.0-notes.html#printing-style-for-void-datatypes-is-now-independently-customizable) -
np.loadtxt的内存使用量减少](release/1.14.0-notes.html#reduced-memory-usage-of-np-loadtxt)
-
-
更改](release/1.14.0-notes.html#changes)
-
结构化数组的多字段索引/赋值](release/1.14.0-notes.html#multiple-field-indexing-assignment-of-structured-arrays)
-
整数和 Void 标量现在不受
np.set_string_function影响](release/1.14.0-notes.html#integer-and-void-scalars-are-now-unaffected-by-np-set-string-function) -
0d 数组打印已更改,已弃用 array2string 的
style参数](release/1.14.0-notes.html#d-array-printing-changed-style-arg-of-array2string-deprecated) -
使用数组播种
RandomState需要一个 1-d 数组](release/1.14.0-notes.html#seeding-randomstate-using-an-array-requires-a-1-d-array) -
MaskedArray对象显示更有用的repr](release/1.14.0-notes.html#maskedarray-objects-show-a-more-useful-repr) -
np.polynomial类的repr更为明确
-
-
-
1.13.3](release/1.13.3-notes.html)
-
贡献者](release/1.13.3-notes.html#contributors)
-
合并的拉取请求](release/1.13.3-notes.html#pull-requests-merged)
-
-
1.13.2](release/1.13.2-notes.html)
-
贡献者
-
合并的 Pull 请求
-
-
1.13.1
-
合并的 Pull 请求
-
贡献者
-
-
1.13.0
-
亮点
-
新的函数
-
弃用
-
未来的更改
-
构建系统更改
-
兼容性说明
-
错误类型更改
-
元组对象数据类型
-
DeprecationWarning 转为 error
-
将 FutureWarning 更改为已更改的行为
-
数据类型现在总是为 true
-
__getslice__和__setslice__在ndarray子类中不再需要 -
使用
...(省略号)索引 MaskedArrays/Constants 现在返回 MaskedArray
-
-
C API 更改
-
在空数组和 NpyIter 中使用 GUfuncs 轴移除
-
添加了
PyArray_MapIterArrayCopyIfOverlap到 NumPy C-API
-
-
新特性
-
添加了
__array_ufunc__ -
新的
positiveufunc -
新的
divmodufunc -
np.isnatufunc 用于测试 NaT 特殊日期和时间差值的值 -
np.heavisideufunc 计算 Heaviside 函数 -
用于创建 blocked 数组的
np.block函数 -
isin函数,改进in1d -
临时省略
-
unique的axes参数 -
np.gradient现在支持不均匀间隔的数据 -
支持在
apply_along_axis中返回任意维度的数组 -
dtype添加了.ndim属性来补充.shape(查看详情) -
Python 3.6 对 tracemalloc 的支持(查看详情)
-
NumPy 可以使用放松的步幅检查调试构建(查看详情)
-
-
改进(查看详情)
-
重叠输入的 ufunc 行为(查看详情)
-
MinGW 上对于 64 位 f2py 扩展的部分支持(查看详情)
-
packbits和unpackbits的性能改进(查看详情) -
PPC 长双浮点信息的修复(查看详情)
-
ndarray子类的更好的默认 repr(查看详情) -
更可靠的掩码数组比较(查看详情)
-
np.matrix中的布尔元素现在可以使用字符串语法创建(查看详情) -
更多
linalg操作现在接受空向量和矩阵(查看详情) -
捆绑版本的 LAPACK 现在是 3.2.2(查看详情)
-
np.hypot.reduce和np.logical_xor的reduce在更多情况下被允许(查看详情) -
对象数组的更好
repr(查看详情)
-
-
改变(查看详情)
-
对掩码数组进行的
argsort现在具有与sort相同的默认参数(查看详情) -
average现在保留子类(查看详情) -
array == None和array != None现在进行按元素比较(查看详情) -
对于对象数组,
np.equal, np.not_equal忽略对象身份(查看详情) -
布尔索引变化(查看详情)
-
np.random.multivariate_normal在坏协方差矩阵下的行为(查看详情) -
assert_array_less现在对比np.inf和-np.inf(查看详情) -
assert_array_和屏蔽数组assert_equal隐藏了较少的警告 -
memmap对象中的offset属性值 -
np.real和np.imag为标量输入返回标量 -
多项式便利类不能传递给 ufuncs
-
对 ufunc 方法,ufunc 的输出参数也可以是元组
-
-
-
1.12.1
- 修复的错误
-
1.12.0
-
亮点
-
弃用的支持
-
新增支持
-
构建系统变更
-
废弃
-
ndarray 对象的
data属性分配 -
linspace中 num 属性的不安全的整型转换 -
binary_repr的位宽参数不足
-
-
未来变更
- 结构化数组的多字段操作
-
兼容性注意事项
-
DeprecationWarning 变成错误
-
FutureWarning 的变更行为
-
整数的负指数幂,
power和**会报错 -
放宽了步幅检查的默认设置
-
np.percentile的“midpoint”插值方法修复确切指数 -
keepdims参数传递给用户类方法 -
bitwise_and的身份变化 -
ma.median 在遇到非屏蔽的无效值时发出警告并返回 nan
-
assert_almost_equal更加一致 -
NoseTester在测试期间的警告行为 -
assert_warns和deprecated装饰器更具体 -
C API
-
-
新功能
-
as_strided的writeable关键字参数 -
rot90的axes关键字参数 -
通用的
flip -
numpy.distutils中的 BLIS 支持 -
在
numpy/__init__.py中加入运行分发特定检查的钩子 -
新增的
nancumsum和nancumprod函数 -
np.interp现在可以插值复数值 -
新增的多项式评估函数
polyvalfromroots -
新增的数组创建函数
geomspace -
用于测试警告的新上下文管理器
-
新增的屏蔽数组函数
ma.convolve和ma.correlate -
新的
float_power通用函数 -
现在
np.loadtxt支持单个整数作为usecol参数 -
histogram的改进的自动化箱估计器 -
np.roll现在可以同时滚动多个轴 -
对于 ndarrays,已实现
__complex__方法 -
现在支持
pathlib.Path对象 -
np.finfo的新bits属性 -
np.vectorize的新signature参数 -
对整数数组的除法现在会发出 py3kwarnings
-
numpy.sctypes现在在 Python3 中也包括bytes
-
-
改进
-
bitwise_and的特性变化 -
广义 Ufuncs 现在将解锁 GIL
-
np.fft中的缓存现在在总大小和项目数量上已限定
-
改进了零宽字符串/unicode 数据类型的处理
-
使用 AVX2 向量化的整数 ufuncs
-
np.einsum中的操作次序优化 -
quicksort 已更改为 introsort
-
ediff1d提高了性能和 subclass 处理 -
改善了 float16 数组的
ndarray.mean精度
-
-
更改
-
现在在 fromnumeric.py 中的所有类似数组的方法都使用关键字参数调用
-
大多数情况下,np.memmap 对象的操作返回 numpy 数组
-
增加警告的 stacklevel
-
-
-
1.11.3
-
贡献者维护/1.11.3
-
已合并的 Pull Requests
-
-
1.11.2
- 已合并的 Pull Requests
-
1.11.1
- 已合并的修复
-
1.11.0
-
亮点
-
构建系统更改
-
未来的改变
-
兼容性说明
-
datetime64 更改
-
linalg.norm返回类型更改 -
多项式拟合更改
-
np.dot现在引发
TypeError而不是ValueError -
FutureWarning 更改行为
-
%和//运算符 -
C API
-
检测旧式类的对象数据类型
-
-
新特性
-
改进
-
np.gradient现在支持axis参数](release/1.11.0-notes.html#np-gradient-now-supports-an-axis-argument) -
np.lexsort现在支持具有对象数据类型的数组](release/1.11.0-notes.html#np-lexsort-now-supports-arrays-with-object-data-type) -
np.ma.core.MaskedArray现在支持order参数](release/1.11.0-notes.html#np-ma-core-maskedarray-now-supports-an-order-argument) -
对掩码数组的内存和速度改进
-
ndarray.tofile现在在 linux 上使用 fallocate](release/1.11.0-notes.html#ndarray-tofile-now-uses-fallocate-on-linux) -
A.T @ A和A @ A.T形式操作的优化](release/1.11.0-notes.html#optimizations-for-operations-of-the-form-a-t-a-and-a-a-t) -
np.testing.assert_warns现在可以作为上下文管理器使用](release/1.11.0-notes.html#np-testing-assert-warns-can-now-be-used-as-a-context-manager) -
对 np.random.shuffle 的速度改进
-
-
变更
-
numpy.distutils中删除了 Pyrex 支持](release/1.11.0-notes.html#pyrex-support-was-removed-from-numpy-distutils) -
np.broadcast现在可以用单个参数调用](release/1.11.0-notes.html#np-broadcast-can-now-be-called-with-a-single-argument) -
np.trace现在尊重数组子类](release/1.11.0-notes.html#np-trace-now-respects-array-subclasses) -
np.dot现在引发TypeError而不是ValueError](release/1.11.0-notes.html#id1) -
linalg.norm返回类型发生变化](release/1.11.0-notes.html#id2)
-
-
弃用内容
-
以 Fortran 排序的数组视图](release/1.11.0-notes.html#views-of-arrays-in-fortran-order)
-
数组排序的无效参数](release/1.11.0-notes.html#invalid-arguments-for-array-ordering)
-
testing命名空间中的随机数生成器 -
在闭区间上生成随机整数
-
-
FutureWarnings
- 对
MaskedArray的切片/视图赋值
- 对
-
-
1.10.4
-
兼容性说明
-
已解决的问题
-
合并的 PR
-
-
1.10.3
-
1.10.2
-
兼容性说明
-
放宽的步幅检查不再是默认设置
-
修复
numpy.i中的 swig bug -
弃用修改维度为 fortran 排序的视图
-
-
已解决的问题
-
合并的 PRs
-
注意事项
-
-
1.10.1
-
1.10.0
-
亮点
-
已弃用的支持
-
未来变化
-
兼容性注意事项
-
默认转换规则改变
-
numpy 版本字符串
-
放松的步幅检查
-
沿着除
axis=0之外的任何轴对 1d 数组进行连接都会引发IndexError -
np.ravel,np.diagonal 和 np.diag 现在保留子类型
-
rollaxis 和 swapaxes 总是返回视图
-
非零 现在返回基本 ndarrays
-
C API
-
recarray 字段返回类型
-
recarray 视图
-
ufunc 的’out’关键字参数现在接受数组的元组
-
byte-array 索引现在会引发 IndexError
-
包含带有数组的对象的掩码数组
-
当遇到无效值时,中位数会发出警告并返回 nan
-
从 numpy.ma.testutils 中可用的函数已更改
-
-
新功能
-
从 site.cfg 读取额外标志
-
np.cbrt 用于计算实浮点数的立方根
-
numpy.distutil 现在允许并行编译
-
genfromtxt 现在有一个新的
max_rows参数 -
用于调用数组广播的新函数np.broadcast_to
-
用于测试警告的新上下文管理器clear_and_catch_warnings
-
cov 新增
fweights和aweights参数 -
支持 Python 3.5+ 中的 ‘@’ 运算符
-
fft 函数的新参数
norm
-
-
改进
-
np.digitize 使用二进制搜索
-
np.poly 现在将整数输入转换为浮点数
-
np.interp 现在可用于周期函数
-
np.pad 支持更多输入类型的
pad_width和constant_values -
np.argmax 和 np.argmin 现在支持
out参数 -
发现并使用更多系统 C99 复数函数](release/1.10.0-notes.html#more-system-c99-complex-functions-detected-and-used)
-
np.loadtxt 支持由
float.hex方法生成的字符串 -
np.isclose 正确处理整数数据类型的最小值
-
np.allclose 内部使用 np.isclose。
-
np.genfromtxt 现在能正确处理大整数
-
np.load, np.save 具有 pickle 向后兼容标志
-
MaskedArray 支持更复杂的基类
-
-
变更
-
dotblas 功能移至 multiarray
-
更严格地检查 gufunc 签名是否符合规范
-
np.einsum 返回的视图可写入
-
np.argmin 跳过 NaT 值
-
-
已弃用
-
涉及字符串或结构化数据类型的数组比较
-
SafeEval
-
alterdot, restoredot
-
pkgload, PackageLoader
-
corrcoef 的 bias, ddof 参数
-
dtype string representation changes
-
-
-
1.9.2
- Issues fixed
-
1.9.1
- Issues fixed
-
1.9.0
-
Highlights
-
Dropped Support
-
Future Changes
-
Compatibility notes
-
The diagonal and diag functions return readonly views.
-
Special scalar float values don’t cause upcast to double anymore
-
Percentile output changes
-
ndarray.tofile exception type
-
Invalid fill value exceptions
-
Polynomial Classes no longer derived from PolyBase
-
Using numpy.random.binomial may change the RNG state vs. numpy < 1.9
-
Random seed enforced to be a 32 bit unsigned integer
-
Argmin and argmax out argument
-
Einsum
-
Indexing
-
Non-integer reduction axis indexes are deprecated
-
promote_typesand string dtype -
can_castand string dtype -
astype and string dtype
-
npyio.recfromcsv keyword arguments change
-
The
doc/swigdirectory moved -
The
npy_3kcompat.hheader changed -
Negative indices in C-Api
sq_itemandsq_ass_itemsequence methods -
NDIter
-
zeros_likefor string dtypes now returns empty strings
-
-
New Features
-
Percentile supports more interpolation options
-
对中位数和百分位数的广义轴支持。
-
np.linspace 和 np.logspace 添加了
Dtype参数。 -
对
np.triu和np.tril的更一般的广播支持。 -
tostring方法的tobytes别名。 -
构建系统。
-
对 python
numbers模块的兼容性。 -
对
np.vander添加了increasing参数。 -
np.unique添加了unique_counts参数。 -
nanfunctions中对中位数和百分位数的支持。 -
添加了 NumpyVersion 类。
-
允许保存具有大量命名列的数组。
-
np.cross的全广播支持。
-
-
改进。
-
在某些情况下,对求和的更好的数值稳定性。
-
基于
np.partition实现的百分位数。 -
对
np.array的性能改进。 -
对
np.searchsorted的性能改进。 -
np.distutils 的可选降低冗余度。
-
在
np.random.multivariate_normal中的协方差检查。 -
多项式类不再是基于模板的。
-
更多 GIL 释放。
-
对更复杂的基类的 MaskedArray 支持。
-
C-API。
-
-
弃用。
-
序列重复的非整数标量。
-
select输入的弃用。 -
rank函数。 -
对象数组的相等比较。
-
C-API。
-
-
-
1.8.2
- 修复的问题。
-
1.8.1
-
已解决的问题
-
变化
-
NDIter
-
np.distutils 的可选减少冗余性
-
-
弃用内容
- C-API
-
-
1.8.0
-
亮点
-
中止支持
-
未来的变化
-
兼容性说明
-
NPY_RELAXED_STRIDES_CHECKING
-
使用非数组作为第二参数的二进制运算
-
只部分排序数组时,median 函数使用 overwrite_input
-
financial.npv 的修复
-
当比较 NaN 数时的运行时警告
-
-
新功能
-
对堆叠数组进行线性代数支持
-
ufuncs 的原位花式索引
-
新函数 partition 和 argpartition
-
新函数 nanmean, nanvar 和 nanstd
-
新函数 full 和 full_like
-
与大文件兼容的 IO 性能
-
针对 OpenBLAS 的构建改进
-
新常数
-
qr 的新模式
-
in1d 的新 invert 参数
-
使用 np.newaxis 进行高级索引
-
C-API
-
runtests.py
-
-
改进
-
IO 性能改进
-
对 pad 进行性能改进
-
对 isnan, isinf, isfinite 和 byteswap 进行性能改进
-
通过 SSE2 向量化进行的性能改进
-
对 median 的性能改进
-
在 ufunc C-API 中可覆盖的操作标志
-
-
变更
-
通用
-
C-API 数组新增内容
-
C-API Ufunc 新增内容
-
C-API 开发者改进
-
-
弃用
- 通用
-
作者
-
-
1.7.2
- 修复的问题
-
1.7.1
- 修复的问题
-
1.7.0
-
亮点
-
兼容性注意事项
-
新功能
-
降维 UFuncs 通用 axis= 参数
-
降维 UFuncs 新的 keepdims= 参数
-
日期时间支持
-
打印数组的自定义格式化程序
-
新函数 numpy.random.choice
-
新函数 isclose
-
多项式包中初步的多维支持
-
能够填充秩为 n 的数组
-
searchsorted 新参数
-
构建系统
-
C API
-
-
变更
-
通用
-
转换规则
-
-
弃用
-
通用
-
C-API
-
-
-
1.6.2
-
修复的问题
-
numpy.core -
numpy.lib -
numpy.distutils -
numpy.random
-
-
变更
-
numpy.f2py -
numpy.poly
-
-
-
1.6.1
- 修复的问题
-
1.6.0
-
亮点
-
新功能
-
新的 16 位浮点类型
-
新的迭代器
-
numpy.polynomial中的 Legendre、Laguerre、Hermite、HermiteE 多项式 -
numpy.f2py中支持 Fortran 隐式形状数组和大小函数 -
其他新功能
-
-
更改
-
默认错误处理 -
numpy.distutils -
numpy.testing -
C API
-
-
废弃功能
-
删除的功能
-
numpy.fft -
numpy.memmap -
numpy.lib -
numpy.ma -
numpy.distutils
-
-
-
1.5.0
-
亮点
-
Python 3 兼容性
-
PEP 3118 兼容性](release/1.5.0-notes.html#pep-3118-compatibility)
-
-
新功能
-
复数到实数转换的警告
-
ndarrays 的 Dot 方法
-
linalg.slogdet 函数
-
新标题
-
-
更改
-
polynomial.polynomial
-
polynomial.chebyshev
-
直方图
-
相关性
-
-
-
1.4.0
-
亮点
-
新功能
-
ufuncs 的扩展数组包装机制
-
前向不兼容性的自动检测
-
新迭代器
-
新的多项式支持
-
新的 C API
-
新的 ufuncs
-
新定义
-
测试
-
重新使用 npymath
-
增强的集合操作
-
-
改进
-
弃用信息
-
内部更改
-
使用 C99 复数函数(在可用时)
-
分离多维数组和 umath 源代码
-
分离编译
-
独立的核心数学库
-
-
-
1.3.0
-
亮点
-
Python 2.6 支持
-
广义 ufuncs
-
实验性的 Windows 64 位支持
-
-
新特性
-
格式问题
-
max/min 中的 Nan 处理
-
sign 中的 Nan 处理
-
新的 ufuncs
-
掩码数组
-
Windows 上的 gfortran 支持
-
用于 Windows 二进制的 Arch 选项
-
-
已弃用的功能
- 直方图
-
文档更改
-
新的 C API
-
多维数组 API
-
Ufunc API
-
新定义
-
便携式 NAN、INFINITY 等…
-
-
内部更改
-
numpy 核心数学配置更新
-
umath 重构
-
构建警告的改进
-
独立的核心数学库
-
CPU 架构检测
-
-


浙公网安备 33010602011771号