我如何使用np.newaxi ?

什么是numpy.newaxis,什么时候应该使用它?

在一维数组x上使用它会产生:

>>> x
array([0, 1, 2, 3])


>>> x[np.newaxis, :]
array([[0, 1, 2, 3]])


>>> x[:, np.newaxis]
array([[0],
[1],
[2],
[3]])
368960 次浏览

你从一个一维的数字列表开始。一旦你使用了numpy.newaxis,你就把它变成了一个二维矩阵,由四行每行一列组成。

然后你可以用这个矩阵做矩阵乘法,或者用它来构造一个更大的4 × n矩阵。

简单地说,当使用一次时,numpy.newaxis另一个维度用于现有数组的增加维度。因此,

  • 1 d数组将变成二维数组

  • 二维数组将变成3 d数组

  • 3 d数组将变成4 d数组

  • 4 d数组将变成5 d数组

等等。

下面是一个可视化的插图,描绘了1D数组到2D数组的促销活动

newaxis canva visualization


场景1:当你想要显式地将一个一维数组转换为行向量列向量时,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])

如果你试图像这样添加它们,NumPy将引发以下ValueError:

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 kwarg。

# 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 vs np.重塑

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

附注:还可以看到这个很棒的答案:Newaxis vs重塑增加维度

选择元组中的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不仅仅是行到列矩阵的转换。它增加了矩阵的维数,从而使我们能够对矩阵进行更多的操作。

np.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中插入__abc0,你也可以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 可以广播数组。这是因为每个length-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.]])