NumPy 1.26 中文官方指南(一)(3)

简介: NumPy 1.26 中文官方指南(一)

NumPy 1.26 中文官方指南(一)(2)https://developer.aliyun.com/article/1510632

一个例子

>>> import numpy as np
>>> a = np.arange(15).reshape(3, 5)
>>> a
array([[ 0,  1,  2,  3,  4],
 [ 5,  6,  7,  8,  9],
 [10, 11, 12, 13, 14]])
>>> a.shape
(3, 5)
>>> a.ndim
2
>>> a.dtype.name
'int64'
>>> a.itemsize
8
>>> a.size
15
>>> type(a)
<class 'numpy.ndarray'>
>>> b = np.array([6, 7, 8])
>>> b
array([6, 7, 8])
>>> type(b)
<class 'numpy.ndarray'> 

数组创建

有几种创建数组的方法。

例如,您可以使用array函数从常规 Python 列表或元组创建数组。结果数组的类型是从序列中元素的类型推断出来的。

>>> import numpy as np
>>> a = np.array([2, 3, 4])
>>> a
array([2, 3, 4])
>>> a.dtype
dtype('int64')
>>> b = np.array([1.2, 3.5, 5.1])
>>> b.dtype
dtype('float64') 

一个常见错误是使用多个参数调用array,而不是提供一个序列作为参数。

>>> a = np.array(1, 2, 3, 4)    # WRONG
Traceback (most recent call last):
  ...
TypeError: array() takes from 1 to 2 positional arguments but 4 were given
>>> a = np.array([1, 2, 3, 4])  # RIGHT 

array将序列转换为二维数组,序列的序列转换为三维数组,依此类推。

>>> b = np.array([(1.5, 2, 3), (4, 5, 6)])
>>> b
array([[1.5, 2\. , 3\. ],
 [4\. , 5\. , 6\. ]]) 

数组的类型也可以在创建时显式指定:

>>> c = np.array([[1, 2], [3, 4]], dtype=complex)
>>> c
array([[1.+0.j, 2.+0.j],
 [3.+0.j, 4.+0.j]]) 

通常,数组的元素最初是未知的,但其大小是已知的。因此,NumPy 提供了几个函数来创建具有初始占位内容的数组。这减少了增长数组的必要性,这是一个昂贵的操作。

函数zeros创建一个全零数组,函数ones创建一个全一数组,函数empty创建一个其初始内容是随机的并且取决于内存状态的数组。默认情况下,创建的数组的 dtype 是float64,但可以通过关键字参数dtype进行指定。

>>> np.zeros((3, 4))
array([[0., 0., 0., 0.],
 [0., 0., 0., 0.],
 [0., 0., 0., 0.]])
>>> np.ones((2, 3, 4), dtype=np.int16)
array([[[1, 1, 1, 1],
 [1, 1, 1, 1],
 [1, 1, 1, 1]],
 [[1, 1, 1, 1],
 [1, 1, 1, 1],
 [1, 1, 1, 1]]], dtype=int16)
>>> np.empty((2, 3)) 
array([[3.73603959e-262, 6.02658058e-154, 6.55490914e-260],  # may vary
 [5.30498948e-313, 3.14673309e-307, 1.00000000e+000]]) 

为了创建数字序列,NumPy 提供了类似于 Python 内置的rangearange函数,但它返回一个数组。

>>> np.arange(10, 30, 5)
array([10, 15, 20, 25])
>>> np.arange(0, 2, 0.3)  # it accepts float arguments
array([0\. , 0.3, 0.6, 0.9, 1.2, 1.5, 1.8]) 

arange与浮点数参数一起使用时,通常无法预测获得的元素数量,这是由于有限浮点精度。因此,通常最好使用接收我们想要的元素数量作为参数而不是步长的函数linspace

>>> from numpy import pi
>>> np.linspace(0, 2, 9)                   # 9 numbers from 0 to 2
array([0\.  , 0.25, 0.5 , 0.75, 1\.  , 1.25, 1.5 , 1.75, 2\.  ])
>>> x = np.linspace(0, 2 * pi, 100)        # useful to evaluate function at lots of points
>>> f = np.sin(x) 

另请参阅

array, zeros, zeros_like, ones, ones_like, empty, empty_like, arange, linspace, numpy.random.Generator.rand, numpy.random.Generator.randn, fromfunction, fromfile

打印数组

当打印数组时,NumPy 以类似嵌套列表的方式显示它,但布局如下:

  • 最后一个轴从左到右打印,
  • 倒数第二个从上到下打印,
  • 剩余部分也从上到下打印,每个切片与下一个切片之间由一个空行分隔。

一维数组被打印为行,二维数组被打印为矩阵,三维数组被打印为矩阵的列表。

>>> a = np.arange(6)                    # 1d array
>>> print(a)
[0 1 2 3 4 5]
>>>
>>> b = np.arange(12).reshape(4, 3)     # 2d array
>>> print(b)
[[ 0  1  2]
 [ 3  4  5]
 [ 6  7  8]
 [ 9 10 11]]
>>>
>>> c = np.arange(24).reshape(2, 3, 4)  # 3d array
>>> print(c)
[[[ 0  1  2  3]
 [ 4  5  6  7]
 [ 8  9 10 11]]
 [[12 13 14 15]
 [16 17 18 19]
 [20 21 22 23]]] 

请参见下面以获取有关reshape的更多详细信息。

如果数组太大而无法打印,NumPy 会自动跳过数组的中间部分,仅打印角落:

>>> print(np.arange(10000))
[   0    1    2 ... 9997 9998 9999]
>>>
>>> print(np.arange(10000).reshape(100, 100))
[[   0    1    2 ...   97   98   99]
 [ 100  101  102 ...  197  198  199]
 [ 200  201  202 ...  297  298  299]
 ...
 [9700 9701 9702 ... 9797 9798 9799]
 [9800 9801 9802 ... 9897 9898 9899]
 [9900 9901 9902 ... 9997 9998 9999]] 

要禁用此行为并强制 NumPy 打印整个数组,可以使用set_printoptions更改打印选项。

>>> np.set_printoptions(threshold=sys.maxsize)  # sys module should be imported 

基本操作

数组上的算术运算逐元素应用。创建一个新数组并用结果填充。

>>> a = np.array([20, 30, 40, 50])
>>> b = np.arange(4)
>>> b
array([0, 1, 2, 3])
>>> c = a - b
>>> c
array([20, 29, 38, 47])
>>> b**2
array([0, 1, 4, 9])
>>> 10 * np.sin(a)
array([ 9.12945251, -9.88031624,  7.4511316 , -2.62374854])
>>> a < 35
array([ True,  True, False, False]) 

与许多矩阵语言不同,在 NumPy 数组中,乘积运算符*是按元素操作的。可以使用@运算符(在 python >=3.5 中)或dot函数或方法执行矩阵乘积:

>>> A = np.array([[1, 1],
...               [0, 1]])
>>> B = np.array([[2, 0],
...               [3, 4]])
>>> A * B     # elementwise product
array([[2, 0],
 [0, 4]])
>>> A @ B     # matrix product
array([[5, 4],
 [3, 4]])
>>> A.dot(B)  # another matrix product
array([[5, 4],
 [3, 4]]) 

一些操作,比如+=*=,是就地修改现有数组而不是创建新数组。

>>> rg = np.random.default_rng(1)  # create instance of default random number generator
>>> a = np.ones((2, 3), dtype=int)
>>> b = rg.random((2, 3))
>>> a *= 3
>>> a
array([[3, 3, 3],
 [3, 3, 3]])
>>> b += a
>>> b
array([[3.51182162, 3.9504637 , 3.14415961],
 [3.94864945, 3.31183145, 3.42332645]])
>>> a += b  # b is not automatically converted to integer type
Traceback (most recent call last):
  ...
numpy.core._exceptions._UFuncOutputCastingError: Cannot cast ufunc 'add' output from dtype('float64') to dtype('int64') with casting rule 'same_kind' 

在操作不同类型的数组时,结果数组的类型对应于更一般或更精确的类型(这种行为称为向上转型)。

>>> a = np.ones(3, dtype=np.int32)
>>> b = np.linspace(0, pi, 3)
>>> b.dtype.name
'float64'
>>> c = a + b
>>> c
array([1\.        , 2.57079633, 4.14159265])
>>> c.dtype.name
'float64'
>>> d = np.exp(c * 1j)
>>> d
array([ 0.54030231+0.84147098j, -0.84147098+0.54030231j,
 -0.54030231-0.84147098j])
>>> d.dtype.name
'complex128' 

许多一元操作,比如计算数组中所有元素的和,都作为ndarray类的方法实现。

>>> a = rg.random((2, 3))
>>> a
array([[0.82770259, 0.40919914, 0.54959369],
 [0.02755911, 0.75351311, 0.53814331]])
>>> a.sum()
3.1057109529998157
>>> a.min()
0.027559113243068367
>>> a.max()
0.8277025938204418 

默认情况下,这些操作会将数组视为数字列表进行,而不考虑其形状。但是,通过指定axis参数,您可以沿着数组的指定轴应用操作:

>>> b = np.arange(12).reshape(3, 4)
>>> b
array([[ 0,  1,  2,  3],
 [ 4,  5,  6,  7],
 [ 8,  9, 10, 11]])
>>>
>>> b.sum(axis=0)     # sum of each column
array([12, 15, 18, 21])
>>>
>>> b.min(axis=1)     # min of each row
array([0, 4, 8])
>>>
>>> b.cumsum(axis=1)  # cumulative sum along each row
array([[ 0,  1,  3,  6],
 [ 4,  9, 15, 22],
 [ 8, 17, 27, 38]]) 

通用函数

NumPy 提供了一些熟悉的数学函数,如 sin、cos 和 exp。在 NumPy 中,这些被称为“通用函数”(ufunc)。在 NumPy 中,这些函数对数组进行逐元素操作,并产生一个数组作为输出。

>>> B = np.arange(3)
>>> B
array([0, 1, 2])
>>> np.exp(B)
array([1\.        , 2.71828183, 7.3890561 ])
>>> np.sqrt(B)
array([0\.        , 1\.        , 1.41421356])
>>> C = np.array([2., -1., 4.])
>>> np.add(B, C)
array([2., 0., 6.]) 

另见

all, any, apply_along_axis, argmax, argmin, argsort, average, bincount, ceil, clip, conj, corrcoef, cov, cross, cumprod, cumsum, diff, dot, floor, inner, invert, lexsort, max, maximum, mean, median, min, minimum, nonzero, outer, prod, re, round, sort, std, sum, trace, transpose, var, vdot, vectorize, where

索引、切片和迭代

一维数组可以像列表和其他 Python 序列一样进行索引、切片和迭代。

>>> a = np.arange(10)**3
>>> a
array([  0,   1,   8,  27,  64, 125, 216, 343, 512, 729])
>>> a[2]
8
>>> a[2:5]
array([ 8, 27, 64])
>>> # equivalent to a[0:6:2] = 1000;
>>> # from start to position 6, exclusive, set every 2nd element to 1000
>>> a[:6:2] = 1000
>>> a
array([1000,    1, 1000,   27, 1000,  125,  216,  343,  512,  729])
>>> a[::-1]  # reversed a
array([ 729,  512,  343,  216,  125, 1000,   27, 1000,    1, 1000])
>>> for i in a:
...     print(i**(1 / 3.))
...
9.999999999999998  # may vary
1.0
9.999999999999998
3.0
9.999999999999998
4.999999999999999
5.999999999999999
6.999999999999999
7.999999999999999
8.999999999999998 

多维数组可以有每个轴的一个索引。这些索引用逗号分隔的元组给出:

>>> def f(x, y):
...     return 10 * x + y
...
>>> b = np.fromfunction(f, (5, 4), dtype=int)
>>> b
array([[ 0,  1,  2,  3],
 [10, 11, 12, 13],
 [20, 21, 22, 23],
 [30, 31, 32, 33],
 [40, 41, 42, 43]])
>>> b[2, 3]
23
>>> b[0:5, 1]  # each row in the second column of b
array([ 1, 11, 21, 31, 41])
>>> b[:, 1]    # equivalent to the previous example
array([ 1, 11, 21, 31, 41])
>>> b[1:3, :]  # each column in the second and third row of b
array([[10, 11, 12, 13],
 [20, 21, 22, 23]]) 

当提供的索引少于轴的数量时,缺少的索引被视为完整切片

>>> b[-1]   # the last row. Equivalent to b[-1, :]
array([40, 41, 42, 43]) 

表达式b[i]中的括号内被视为i后面跟着尽可能多的:来表示剩下的轴。NumPy 还允许您使用点号表示为b[i, ...]

省略号...)表示为产生一个完整索引元组所需的冒号。例如,如果x是一个具有 5 个轴的数组,则

  • x[1, 2, ...]等同于x[1, 2, :, :, :]
  • x[..., 3]x[:, :, :, :, 3]
  • x[4, ..., 5, :]x[4, :, :, 5, :]
>>> c = np.array([[[  0,  1,  2],  # a 3D array (two stacked 2D arrays)
...                [ 10, 12, 13]],
...               [[100, 101, 102],
...                [110, 112, 113]]])
>>> c.shape
(2, 2, 3)
>>> c[1, ...]  # same as c[1, :, :] or c[1]
array([[100, 101, 102],
 [110, 112, 113]])
>>> c[..., 2]  # same as c[:, :, 2]
array([[  2,  13],
 [102, 113]]) 

对多维数组的迭代是针对第一个轴进行的:

>>> for row in b:
...     print(row)
...
[0 1 2 3]
[10 11 12 13]
[20 21 22 23]
[30 31 32 33]
[40 41 42 43] 

但是,如果想要对数组中的每个元素执行操作,可以使用flat属性,它是一个对数组的所有元素进行迭代的迭代器:

>>> for element in b.flat:
...     print(element)
...
0
1
2
3
10
11
12
13
20
21
22
23
30
31
32
33
40
41
42
43 

另见

ndarrays 上的索引,索引例程(参考文档),newaxisndenumerateindices

形状操作

改变数组的形状

数组的形状由每个轴上的元素数量确定:

>>> a = np.floor(10 * rg.random((3, 4)))
>>> a
array([[3., 7., 3., 4.],
 [1., 4., 2., 2.],
 [7., 2., 4., 9.]])
>>> a.shape
(3, 4) 

数组的形状可以使用各种命令来改变。请注意,以下三个命令都会返回一个修改后的数组,但不会改变原始数组:

>>> a.ravel()  # returns the array, flattened
array([3., 7., 3., 4., 1., 4., 2., 2., 7., 2., 4., 9.])
>>> a.reshape(6, 2)  # returns the array with a modified shape
array([[3., 7.],
 [3., 4.],
 [1., 4.],
 [2., 2.],
 [7., 2.],
 [4., 9.]])
>>> a.T  # returns the array, transposed
array([[3., 1., 7.],
 [7., 4., 2.],
 [3., 2., 4.],
 [4., 2., 9.]])
>>> a.T.shape
(4, 3)
>>> a.shape
(3, 4) 

ravel操作中生成的数组的元素顺序通常是“C-style”,即右边的索引“变化最快”,所以下标为a[0, 0]之后的元素是a[0, 1]。如果数组被重新整形为其他形状,这个数组仍然被视为“C-style”。NumPy 通常创建存储在这个顺序中的数组,所以ravel通常不需要复制它的参数,但如果数组是通过对另一个数组切片或使用不寻常的选项创建的,则可能需要复制它。函数ravelreshape还可以使用可选参数指示使用 FORTRAN-style 数组,其中最左边的索引变化得最快。

reshape函数用修改后的形状返回其参数,而ndarray.resize方法修改数组本身:

>>> a
array([[3., 7., 3., 4.],
 [1., 4., 2., 2.],
 [7., 2., 4., 9.]])
>>> a.resize((2, 6))
>>> a
array([[3., 7., 3., 4., 1., 4.],
 [2., 2., 7., 2., 4., 9.]]) 

如果在重整形操作中给出的维度为-1,则其他维度会自动计算:

>>> a.reshape(3, -1)
array([[3., 7., 3., 4.],
 [1., 4., 2., 2.],
 [7., 2., 4., 9.]]) 

另请参阅

ndarray.shape, reshape, resize, ravel

将不同数组堆叠在一起

可以沿不同轴将多个数组堆叠在一起:

>>> a = np.floor(10 * rg.random((2, 2)))
>>> a
array([[9., 7.],
 [5., 2.]])
>>> b = np.floor(10 * rg.random((2, 2)))
>>> b
array([[1., 9.],
 [5., 1.]])
>>> np.vstack((a, b))
array([[9., 7.],
 [5., 2.],
 [1., 9.],
 [5., 1.]])
>>> np.hstack((a, b))
array([[9., 7., 1., 9.],
 [5., 2., 5., 1.]]) 

函数column_stack 将 1D 数组堆叠为列到 2D 数组中。它与 hstack 仅适用于 2D 数组:

>>> from numpy import newaxis
>>> np.column_stack((a, b))  # with 2D arrays
array([[9., 7., 1., 9.],
 [5., 2., 5., 1.]])
>>> a = np.array([4., 2.])
>>> b = np.array([3., 8.])
>>> np.column_stack((a, b))  # returns a 2D array
array([[4., 3.],
 [2., 8.]])
>>> np.hstack((a, b))        # the result is different
array([4., 2., 3., 8.])
>>> a[:, newaxis]  # view `a` as a 2D column vector
array([[4.],
 [2.]])
>>> np.column_stack((a[:, newaxis], b[:, newaxis]))
array([[4., 3.],
 [2., 8.]])
>>> np.hstack((a[:, newaxis], b[:, newaxis]))  # the result is the same
array([[4., 3.],
 [2., 8.]]) 

另一方面,函数row_stack对于任何输入数组都等同于vstack。事实上,row_stackvstack的别名:

>>> np.column_stack is np.hstack
False
>>> np.row_stack is np.vstack
True 

一般而言,对于维数大于两的数组,hstack 沿第二轴堆叠,vstack 沿第一轴堆叠,而 concatenate 允许使用一个可选参数,指定应该发生连接的轴的编号。

注意

在复杂情况下,r_c_ 对于通过沿一个轴堆叠数字创建数组很有用。它们允许使用范围文本 :

>>> np.r_[1:4, 0, 4]
array([1, 2, 3, 0, 4]) 

当与数组一起使用时,r_c_ 在默认行为上类似于 vstackhstack,但允许使用可选参数指定沿其进行连接的轴的编号。

另请参阅

hstack, vstack, column_stack, concatenate, c_, r_

将一个数组分割成几个较小的数组

使用 hsplit,可以沿水平轴分割数组,可以指定要返回的等形状数组的数量,也可以在哪些列之后进行分割:

>>> a = np.floor(10 * rg.random((2, 12)))
>>> a
array([[6., 7., 6., 9., 0., 5., 4., 0., 6., 8., 5., 2.],
 [8., 5., 5., 7., 1., 8., 6., 7., 1., 8., 1., 0.]])
>>> # Split `a` into 3
>>> np.hsplit(a, 3)
[array([[6., 7., 6., 9.],
 [8., 5., 5., 7.]]), array([[0., 5., 4., 0.],
 [1., 8., 6., 7.]]), array([[6., 8., 5., 2.],
 [1., 8., 1., 0.]])]
>>> # Split `a` after the third and the fourth column
>>> np.hsplit(a, (3, 4))
[array([[6., 7., 6.],
 [8., 5., 5.]]), array([[9.],
 [7.]]), array([[0., 5., 4., 0., 6., 8., 5., 2.],
 [1., 8., 6., 7., 1., 8., 1., 0.]])] 

vsplit 沿垂直轴拆分,而 array_split 允许指定沿哪个轴拆分。

改变数组的形状

数组的形状由每个轴上的元素数量决定:

>>> a = np.floor(10 * rg.random((3, 4)))
>>> a
array([[3., 7., 3., 4.],
 [1., 4., 2., 2.],
 [7., 2., 4., 9.]])
>>> a.shape
(3, 4) 

使用各种命令可以更改数组的形状。请注意,以下三个命令都返回修改后的数组,但不会更改原始数组:

>>> a.ravel()  # returns the array, flattened
array([3., 7., 3., 4., 1., 4., 2., 2., 7., 2., 4., 9.])
>>> a.reshape(6, 2)  # returns the array with a modified shape
array([[3., 7.],
 [3., 4.],
 [1., 4.],
 [2., 2.],
 [7., 2.],
 [4., 9.]])
>>> a.T  # returns the array, transposed
array([[3., 1., 7.],
 [7., 4., 2.],
 [3., 2., 4.],
 [4., 2., 9.]])
>>> a.T.shape
(4, 3)
>>> a.shape
(3, 4) 

ravel 产生的数组中元素的顺序通常是“C-style”,即右边的索引“变化最快”,所以 a[0, 0] 后面的元素是 a[0, 1]。如果将数组重新塑形为其他形状,那么数组将再次被视为“C-style”。NumPy 通常创建以此顺序存储的数组,因此 ravel 通常不需要复制其参数,但是如果数组由另一个数组的切片组成或通过使用不寻常的选项创建,则可能需要进行复制。函数 ravelreshape 还可以通过可选参数指示使用 FORTRAN-style 数组,其中左侧索引变化最快。

reshape 函数返回带有修改形状的参数,而 ndarray.resize 方法修改数组本身:

>>> a
array([[3., 7., 3., 4.],
 [1., 4., 2., 2.],
 [7., 2., 4., 9.]])
>>> a.resize((2, 6))
>>> a
array([[3., 7., 3., 4., 1., 4.],
 [2., 2., 7., 2., 4., 9.]]) 

如果在重塑操作中一个维度给定为 -1,则其他维度将自动计算:

>>> a.reshape(3, -1)
array([[3., 7., 3., 4.],
 [1., 4., 2., 2.],
 [7., 2., 4., 9.]]) 

另请参阅

ndarray.shape, reshape, resize, ravel

组合不同的数组

可以沿不同轴堆叠几个数组:

>>> a = np.floor(10 * rg.random((2, 2)))
>>> a
array([[9., 7.],
 [5., 2.]])
>>> b = np.floor(10 * rg.random((2, 2)))
>>> b
array([[1., 9.],
 [5., 1.]])
>>> np.vstack((a, b))
array([[9., 7.],
 [5., 2.],
 [1., 9.],
 [5., 1.]])
>>> np.hstack((a, b))
array([[9., 7., 1., 9.],
 [5., 2., 5., 1.]]) 

函数 column_stack 将 1D 数组依次堆叠为 2D 数组的列。它与 hstack 对于 2D 数组是等效的:

>>> from numpy import newaxis
>>> np.column_stack((a, b))  # with 2D arrays
array([[9., 7., 1., 9.],
 [5., 2., 5., 1.]])
>>> a = np.array([4., 2.])
>>> b = np.array([3., 8.])
>>> np.column_stack((a, b))  # returns a 2D array
array([[4., 3.],
 [2., 8.]])
>>> np.hstack((a, b))        # the result is different
array([4., 2., 3., 8.])
>>> a[:, newaxis]  # view `a` as a 2D column vector
array([[4.],
 [2.]])
>>> np.column_stack((a[:, newaxis], b[:, newaxis]))
array([[4., 3.],
 [2., 8.]])
>>> np.hstack((a[:, newaxis], b[:, newaxis]))  # the result is the same
array([[4., 3.],
 [2., 8.]]) 

另一方面,row_stack函数对任意输入数组等效于vstack。事实上,row_stackvstack的别名:

>>> np.column_stack is np.hstack
False
>>> np.row_stack is np.vstack
True 

一般来说,对于超过两个维度的数组,hstack沿第二轴堆叠,vstack沿第一轴堆叠,而concatenate允许可选参数指定沿哪个轴进行连接。

注意

在复杂情况下,r_c_用于通过沿一个轴堆叠数字来创建数组。它们允许使用区间字面值:

>>> np.r_[1:4, 0, 4]
array([1, 2, 3, 0, 4]) 

当作为数组参数使用时,r_c_与默认的行为下的vstackhstack相似,但允许可选参数指定沿哪个轴连接。

另请参阅

hstackvstackcolumn_stackconcatenatec_r_

将一个数组分割为几个较小的数组

使用hsplit,您可以沿水平轴拆分数组,要么指定返回的等尺寸数组的数量,要么指定分割应该发生的列:

>>> a = np.floor(10 * rg.random((2, 12)))
>>> a
array([[6., 7., 6., 9., 0., 5., 4., 0., 6., 8., 5., 2.],
 [8., 5., 5., 7., 1., 8., 6., 7., 1., 8., 1., 0.]])
>>> # Split `a` into 3
>>> np.hsplit(a, 3)
[array([[6., 7., 6., 9.],
 [8., 5., 5., 7.]]), array([[0., 5., 4., 0.],
 [1., 8., 6., 7.]]), array([[6., 8., 5., 2.],
 [1., 8., 1., 0.]])]
>>> # Split `a` after the third and the fourth column
>>> np.hsplit(a, (3, 4))
[array([[6., 7., 6.],
 [8., 5., 5.]]), array([[9.],
 [7.]]), array([[0., 5., 4., 0., 6., 8., 5., 2.],
 [1., 8., 6., 7., 1., 8., 1., 0.]])] 

vsplit沿垂直轴分割,而array_split允许指定沿哪个轴进行分割。

复制和视图

在操作和操作数组时,它们的数据有时会复制到新数组中,有时不会。这通常是初学者困惑的原因。有三种情况:

没有任何复制

简单赋值不会复制对象或其数据。

>>> a = np.array([[ 0,  1,  2,  3],
...               [ 4,  5,  6,  7],
...               [ 8,  9, 10, 11]])
>>> b = a            # no new object is created
>>> b is a           # a and b are two names for the same ndarray object
True 

Python 将可变对象作为引用传递,因此函数调用不会复制。

>>> def f(x):
...     print(id(x))
...
>>> id(a)  # id is a unique identifier of an object 
148293216  # may vary
>>> f(a)   
148293216  # may vary 

视图或浅复制

不同的数组对象可以共享相同的数据。view方法创建一个新的数组对象,它查看相同的数据。

>>> c = a.view()
>>> c is a
False
>>> c.base is a            # c is a view of the data owned by a
True
>>> c.flags.owndata
False
>>>
>>> c = c.reshape((2, 6))  # a's shape doesn't change
>>> a.shape
(3, 4)
>>> c[0, 4] = 1234         # a's data changes
>>> a
array([[   0,    1,    2,    3],
 [1234,    5,    6,    7],
 [   8,    9,   10,   11]]) 

对数组进行切片会返回一个视图:

>>> s = a[:, 1:3]
>>> s[:] = 10  # s[:] is a view of s. Note the difference between s = 10 and s[:] = 10
>>> a
array([[   0,   10,   10,    3],
 [1234,   10,   10,    7],
 [   8,   10,   10,   11]]) 

深复制

copy方法会完全复制数组及其数据。

>>> d = a.copy()  # a new array object with new data is created
>>> d is a
False
>>> d.base is a  # d doesn't share anything with a
False
>>> d[0, 0] = 9999
>>> a
array([[   0,   10,   10,    3],
 [1234,   10,   10,    7],
 [   8,   10,   10,   11]]) 

有时在切片之后,原始数组不再需要时,应该调用copy。例如,假设a是一个很大的中间结果,而最终结果b只包含a的一小部分,那么在用切片构造b时应该进行深复制:

>>> a = np.arange(int(1e8))
>>> b = a[:100].copy()
>>> del a  # the memory of ``a`` can be released. 

如果使用b = a[:100]ab引用,并且即使执行del aa也会在内存中保留。

函数和方法概述

以下是一些有用的 NumPy 函数和方法名称,按类别排序。请参见 Routines 获取完整列表。

数组创建

arangearraycopyemptyempty_likeeyefromfilefromfunctionidentitylinspacelogspacemgridogridonesones_liker_zeroszeros_like

转换

ndarray.astypeatleast_1datleast_2datleast_3dmat

操作

array_split, column_stack, concatenate, diagonal, dsplit, dstack, hsplit, hstack, ndarray.item, newaxis, ravel, repeat, reshape, resize, squeeze, swapaxes, take, transpose, vsplit, vstack

问题

all, any, nonzero, where

排序

argmax, argmin, argsort, max, min, ptp, searchsorted, sort

操作

choosecompresscumprodcumsuminnerndarray.fillimagprodputputmaskrealsum

基本统计学

covmeanstdvar

基本线性代数

crossdotouterlinalg.svdvdot

完全不复制

简单赋值不会复制对象或其数据。

>>> a = np.array([[ 0,  1,  2,  3],
...               [ 4,  5,  6,  7],
...               [ 8,  9, 10, 11]])
>>> b = a            # no new object is created
>>> b is a           # a and b are two names for the same ndarray object
True 

Python 将可变对象传递为引用,所以函数调用不会复制。

>>> def f(x):
...     print(id(x))
...
>>> id(a)  # id is a unique identifier of an object 
148293216  # may vary
>>> f(a)   
148293216  # may vary 

查看或浅复制

不同的数组对象可以共享相同的数据。view方法创建一个查看相同数据的新数组对象。

>>> c = a.view()
>>> c is a
False
>>> c.base is a            # c is a view of the data owned by a
True
>>> c.flags.owndata
False
>>>
>>> c = c.reshape((2, 6))  # a's shape doesn't change
>>> a.shape
(3, 4)
>>> c[0, 4] = 1234         # a's data changes
>>> a
array([[   0,    1,    2,    3],
 [1234,    5,    6,    7],
 [   8,    9,   10,   11]]) 

对数组进行切片会返回一个视图:

>>> s = a[:, 1:3]
>>> s[:] = 10  # s[:] is a view of s. Note the difference between s = 10 and s[:] = 10
>>> a
array([[   0,   10,   10,    3],
 [1234,   10,   10,    7],
 [   8,   10,   10,   11]]) 

深度复制

copy方法完全复制数组及其数据。

>>> d = a.copy()  # a new array object with new data is created
>>> d is a
False
>>> d.base is a  # d doesn't share anything with a
False
>>> d[0, 0] = 9999
>>> a
array([[   0,   10,   10,    3],
 [1234,   10,   10,    7],
 [   8,   10,   10,   11]]) 

如果原始数组不再需要,有时应在切片后调用copy。例如,假设a是一个巨大的中间结果,最终结果b只包含a的一小部分,那么在使用切片构建b时应进行深拷贝:

>>> a = np.arange(int(1e8))
>>> b = a[:100].copy()
>>> del a  # the memory of ``a`` can be released. 

如果使用b = a[:100]ab引用并且即使执行del a,它也将在内存中持久存在。

函数和方法概览

这是一些有用的 NumPy 函数和方法名称按类别排序的列表。完整的列表请参见 Routines。

创建数组

arange, array, copy, empty, empty_like, eye, fromfile, fromfunction, identity, linspace, logspace, mgrid, ogrid, ones, ones_like, r_, zeros, zeros_like

转换

ndarray.astype, atleast_1d, atleast_2d, atleast_3d, mat

操作

array_split, column_stack, concatenate, diagonal, dsplit, dstack, hsplit, hstack, ndarray.item, newaxis, ravel, repeat, reshape, resize, squeeze, swapaxes, take, transpose, vsplit, vstack

问题

all, any, nonzero, where

排序

argmax, argmin, argsort, max, min, ptp, searchsorted, sort

操作

choose, compress, cumprod, cumsum, inner, ndarray.fill, imag, prod, put, putmask, real, sum

基本统计

cov, mean, std, var

基本线性代数

cross, dot, outer, linalg.svd, vdot

NumPy 1.26 中文官方指南(一)(4)https://developer.aliyun.com/article/1510636

相关文章
|
6月前
|
Python
NumPy 1.26 中文官方指南(五)
NumPy 1.26 中文官方指南(五)
49 1
|
6月前
|
BI 索引 Python
NumPy 1.26 中文官方指南(一)(2)
NumPy 1.26 中文官方指南(一)
86 1
NumPy 1.26 中文官方指南(一)(2)
|
6月前
|
索引 Python
NumPy 1.26 中文官方指南(一)(4)
NumPy 1.26 中文官方指南(一)
65 1
|
6月前
|
存储 程序员 BI
NumPy 1.26 中文官方指南(一)(1)
NumPy 1.26 中文官方指南(一)
71 1
|
6月前
|
存储 程序员 API
NumPy 1.26 中文官方指南(四)(1)
NumPy 1.26 中文官方指南(四)
51 1
|
6月前
|
并行计算 PyTorch 算法框架/工具
NumPy 1.26 中文官方指南(三)(4)
NumPy 1.26 中文官方指南(三)
95 1
|
6月前
|
编译器 C语言 C++
NumPy 1.26 中文官方指南(三)(2)
NumPy 1.26 中文官方指南(三)
92 1
|
6月前
|
存储 数据建模 索引
NumPy 1.26 中文官方指南(三)(1)
NumPy 1.26 中文官方指南(三)
82 1
|
6月前
|
机器学习/深度学习 存储 数据可视化
NumPy 1.26 中文官方指南(二)(4)
NumPy 1.26 中文官方指南(二)
85 1
|
6月前
|
存储 数据可视化 数据挖掘
NumPy 1.26 中文官方指南(二)(2)
NumPy 1.26 中文官方指南(二)
97 0

相关实验场景

更多