什么是numpy.newaxis
,我何时应该使用它?
在1维数组x
上使用它会产生:
>>> x
array([0, 1, 2, 3])
>>> x[np.newaxis, :]
array([[0, 1, 2, 3]])
>>> x[:, np.newaxis]
array([[0],
[1],
[2],
[3]])
什么是numpy.newaxis
,我何时应该使用它?
在1维数组x
上使用它会产生:
>>> x
array([0, 1, 2, 3])
>>> x[np.newaxis, :]
array([[0, 1, 2, 3]])
>>> x[:, np.newaxis]
array([[0],
[1],
[2],
[3]])
numpy.newaxis
时,它被用于将现有数组的维度增加一个维度。因此,
1D 数组将变为 2D 数组
2D 数组将变为 3D 数组
3D 数组将变为 4D 数组
4D 数组将变为 5D 数组
以此类推。
下面是一个可视化示例,展示了将 1D 数组提升为 2D 数组的过程。
场景-1:当你想要将 1D 数组显式转换为行向量或列向量时,np.newaxis
可能会派上用场,就像上面的图片所示。
例如:
# 1D array
In [7]: arr = np.arange(4)
In [8]: arr.shape
Out[8]: (4,)
# make it as row vector by inserting an axis along first dimension
In [9]: row_vec = arr[np.newaxis, :] # arr[None, :]
In [10]: row_vec.shape
Out[10]: (1, 4)
# make it as column vector by inserting an axis along second dimension
In [11]: col_vec = arr[:, np.newaxis] # arr[:, None]
In [12]: col_vec.shape
Out[12]: (4, 1)
场景-2: 当我们想在某些操作中利用numpy广播,例如在数组加法时。
例子:
假设你想要将以下两个数组相加:
x1 = np.array([1, 2, 3, 4, 5])
x2 = np.array([5, 4, 3])
ValueError: operands could not be broadcast together with shapes (5,) (3,)
np.newaxis
来增加其中一个数组的维数,以便NumPy可以进行 广播。In [2]: x1_new = x1[:, np.newaxis] # x1[:, None]
# now, the shape of x1_new is (5, 1)
# array([[1],
# [2],
# [3],
# [4],
# [5]])
In [3]: x1_new + x2
Out[3]:
array([[ 6, 5, 4],
[ 7, 6, 5],
[ 8, 7, 6],
[ 9, 8, 7],
[10, 9, 8]])
或者,您还可以向数组x2
添加新轴:
In [6]: x2_new = x2[:, np.newaxis] # x2[:, None]
In [7]: x2_new # shape is (3, 1)
Out[7]:
array([[5],
[4],
[3]])
In [8]: x1 + x2_new
Out[8]:
array([[ 6, 7, 8, 9, 10],
[ 5, 6, 7, 8, 9],
[ 4, 5, 6, 7, 8]])
注意:请注意,在这两种情况下我们得到了相同的结果(但其中一种是另一种的转置)。
场景-3:这类似于场景-1。但是,您可以使用np.newaxis
多次来将数组提升到更高的维度。对于高阶数组(即张量),有时需要进行这样的操作。
示例:
In [124]: arr = np.arange(5*5).reshape(5,5)
In [125]: arr.shape
Out[125]: (5, 5)
# promoting 2D array to a 5D array
In [126]: arr_5D = arr[np.newaxis, ..., np.newaxis, np.newaxis] # arr[None, ..., None, None]
In [127]: arr_5D.shape
Out[127]: (1, 5, 5, 1, 1)
作为替代方案,您可以使用numpy.expand_dims
,它具有直观的axis
关键字。
# adding new axes at 1st, 4th, and last dimension of the resulting array
In [131]: newaxes = (0, 3, -1)
In [132]: arr_5D = np.expand_dims(arr, axis=newaxes)
In [133]: arr_5D.shape
Out[133]: (1, 5, 5, 1, 1)
关于 np.newaxis 和 np.reshape 的更多背景信息
newaxis
也被称为伪索引,它允许将一个轴临时添加到多维数组中。
np.newaxis
使用切片操作符来重新创建数组,而numpy.reshape
重塑数组以获得所需的布局(假定尺寸匹配,这是进行 reshape
必须的)。
示例
In [13]: A = np.ones((3,4,5,6))
In [14]: B = np.ones((4,6))
In [15]: (A + B[:, np.newaxis, :]).shape # B[:, None, :]
Out[15]: (3, 4, 5, 6)
B
的第一个和第二个轴之间插入了一个临时轴(使用广播)。这里使用np.newaxis
来填充缺失的轴,以使广播操作起作用。
None
代替np.newaxis
;实际上它们是同一对象。In [13]: np.newaxis is None
Out[13]: True
P.S. 还可以参考这个很好的答案:newaxis与reshape添加维度的区别
None
?- 一直都是这样。 - Darkonautnp.newaxis
?np.newaxis
只是Python常量None
的别名,这意味着无论何时使用np.newaxis
,您也可以使用None
:
>>> np.newaxis is None
True
如果你读的代码使用np.newaxis
而不是None
,那么它会更描述性。
np.newaxis
?np.newaxis
通常与切片一起使用。它表示您想要将一个附加维度添加到数组中。 np.newaxis
的位置表示我想要添加维度的位置。
>>> import numpy as np
>>> a = np.arange(10)
>>> a
array([0, 1, 2, 3, 4, 5, 6, 7, 8, 9])
>>> a.shape
(10,)
在第一个示例中,我使用了第一维度的所有元素,并添加了第二个维度:
>>> a[:, np.newaxis]
array([[0],
[1],
[2],
[3],
[4],
[5],
[6],
[7],
[8],
[9]])
>>> a[:, np.newaxis].shape
(10, 1)
第二个示例将一个维度作为第一维添加,然后使用原始数组的第一维中的所有元素作为结果数组的第二维中的元素:
>>> a[np.newaxis, :] # The output has 2 [] pairs!
array([[0, 1, 2, 3, 4, 5, 6, 7, 8, 9]])
>>> a[np.newaxis, :].shape
(1, 10)
同样地,您可以使用多个np.newaxis
来添加多个维度:
>>> a[np.newaxis, :, np.newaxis] # note the 3 [] pairs in the output
array([[[0],
[1],
[2],
[3],
[4],
[5],
[6],
[7],
[8],
[9]]])
>>> a[np.newaxis, :, np.newaxis].shape
(1, 10, 1)
np.newaxis
的替代方案?NumPy中还有一个非常类似的功能:np.expand_dims
,它也可以用于插入一个维度:
>>> np.expand_dims(a, 1) # like a[:, np.newaxis]
>>> np.expand_dims(a, 0) # like a[np.newaxis, :]
但是,考虑到它只在shape
中插入1
,您也可以使用reshape
函数来添加这些维度:
>>> a.reshape(a.shape + (1,)) # like a[:, np.newaxis]
>>> a.reshape((1,) + a.shape) # like a[np.newaxis, :]
大多数情况下,np.newaxis
是添加维度的最简单方法,但了解替代方案也很好。
np.newaxis
?在几个情境下,添加维度很有用:
如果数据应该有指定数量的维度。例如,如果要使用matplotlib.pyplot.imshow
显示1D数组。
如果你想让NumPy广播数组。通过添加一个维度,你可以得到例如一个数组中所有元素之间的差异:a - a[:, np.newaxis]
。这是因为NumPy操作从最后一个维度开始广播 1。
添加必要的维度以使NumPy能够广播数组。这是因为每个长度为1的维度只需广播到其他数组的相应1维度的长度即可。
1 如果想要阅读更多关于广播规则的内容,NumPy文档非常好。它还包括一个关于np.newaxis
的例子:
>>> a = np.array([0.0, 10.0, 20.0, 30.0]) >>> b = np.array([1.0, 2.0, 3.0]) >>> a[:, np.newaxis] + b array([[ 1., 2., 3.], [ 11., 12., 13.], [ 21., 22., 23.], [ 31., 32., 33.]])
numpy.newaxis
,就将其转换为由四行每列一个元素组成的二维矩阵。newaxis
在选择元组中的对象用于扩展结果选择的维度,增加一个单位长度的维度。
它不仅仅是将行矩阵转换成列矩阵。
考虑下面的例子:
In [1]:x1 = np.arange(1,10).reshape(3,3)
print(x1)
Out[1]: array([[1, 2, 3],
[4, 5, 6],
[7, 8, 9]])
In [2]:x1_new = x1[:,np.newaxis]
print(x1_new)
Out[2]:array([[[1, 2, 3]],
[[4, 5, 6]],
[[7, 8, 9]]])
newaxis
在这里添加了额外的维度,x1 的维度为 (3,3),而 X1_new 的维度为 (3,1,3)。In [3]:x2 = np.arange(11,20).reshape(3,3)
print(x2)
Out[3]:array([[11, 12, 13],
[14, 15, 16],
[17, 18, 19]])
将x1_new和x2相加,我们得到:
In [4]:x1_new+x2
Out[4]:array([[[12, 14, 16],
[15, 17, 19],
[18, 20, 22]],
[[15, 17, 19],
[18, 20, 22],
[21, 23, 25]],
[[18, 20, 22],
[21, 23, 25],
[24, 26, 28]]])
newaxis
不仅仅是将行转换为列矩阵。它增加了矩阵的维度,从而使我们能够在其上执行更多操作。arr[newaxis]
等于 expand_dims(arr, 0)
。
arr[:, newaxis]
等于 expand_dims(arr, 1)
。
arr[:, :, newaxis]
等于 expand_dims(arr, 2)
。