为什么numpy切片会产生一维数组?
Why numpy slicing will produce one-dimension array?
我正在通过 YouTube 教程学习 numpy。在一段视频中,他证明了
wine_data_arr[:, 0].shape
其中 wine_data_arr
是从 sklearn
导入的二维 numpy 数组。结果是(178,)
,他说“是一维数组”。但是在数学中,例如这个
[1,2,3]
可以表示一个 1×3 的矩阵,其维度为 2
。所以我的问题是为什么 wine_data_arr[:, 0]
是一维数组?我想这个定义在某些情况下一定有用。那么那情况是怎样的呢?
尝试更具体:在编写 wine_data_arr[:, 0]
时,我提供了 两个 参数,即 :
和 0
,结果是 一个维度。当我写wine_data_arr[:, (0,4)]
时,我仍然提供两个参数:
和(0,4)
,一个元组,结果是两个维度。为什么不都产生二维矩阵?
简短的回答:这是约定。
在深入细节之前,让我澄清一下,例如,NumPy 中的“维数”与数学中的“维数”不同。在数学中,[1, 2, 3]
是一个 three-dimensional 向量,如果需要,也可以是一维矩阵。然而,这里的维数实际上是指数组的“物理”维度,即数组(或矩阵,或张量等)中存在多少个轴。
现在让我回到您的问题,即为什么“这个”特定的数组维度定义有帮助。我接下来要说的有点哲学意义,是我自己的看法。从本质上讲,这一切都归结为程序员之间的交流。例如,当你正在阅读一些 Python 代码的文档并且想知道输出数组的维数时,确定文档可以写“N x M x ...”然后仔细定义什么 N,M 等。 是。但在许多情况下,仅轴数(或 NumPy 中提到的“维数”)可能足以告知您。在这种情况下,文档变得更加清晰易读,同时提供了有关预期结果的足够信息。
即使它们“看起来”相同,向量也与矩阵不同。考虑:
>>> np.array([1,2,3,4])
array([1, 2, 3,4])
>>> np.matrix([1,2,3,4])
matrix([[1, 2, 3,4]])
>>> np.matrix([[1,2],[3,4]])
matrix([[1, 2],
[3, 4]])
当像
那样对 two-dimensional 数组进行切片时
>>> wine_data_arr = np.array([[1,2,3], [4,5,6], [7,8,9]])
>>> wine_data_arr
array([[1, 2, 3],
[4, 5, 6],
[7, 8, 9]])
您可以使用整数索引请求 lower-dimensional 组件(单个行或列)
>>> wine_data_arr[:,0]
array([1, 4, 7])
>>> wine_data_arr[0,:]
array([1, 2, 3])
或 same-dimensional 使用切片索引的“片段”:
>>> wine_data_arr[:, 0:1]
array([[1],
[4],
[7]])
如果您使用 两个 整数索引,您将得到数组的单个 zero-dimensional 元素:
>>> wine_data_arr[0,0]
1
在 numpy
中,数组可以有 0、1、2 或更多维度。与 MATLAB 相比,没有 2d 下边界。此外 numpy
在显示和索引方面与 Python 列表基本一致。 MATLAB 通常遵循线性代数约定,但我确信数组和向量还有其他数学定义。在物理学中 vector
表示 space 中的一个点或一个方向,而不是 2d 'column vector' 或 'row vector'.
列表:
In [159]: alist = [1, 2, 3]
In [160]: len(alist)
Out[160]: 3
由这个列表组成的数组:
In [161]: arr = np.array(alist)
In [162]: arr.shape
Out[162]: (3,)
索引列表会移除一层嵌套。对数组进行标量索引会删除一个维度。参见
https://numpy.org/doc/stable/user/basics.indexing.html
In [163]: alist[0]
Out[163]: 1
In [164]: arr[0]
Out[164]: 1
一个二维数组:
In [166]: marr = np.arange(4).reshape(2, 2)
In [167]: marr
Out[167]:
array([[0, 1],
[2, 3]])
同样,标量索引删除了一个维度:
In [169]: marr[0,:]
Out[169]: array([0, 1])
In [170]: marr[:, 0]
Out[170]: array([0, 2])
In [172]: marr[1, 1]
Out[172]: 3
使用列表或切片建立索引保留维度:
In [173]: marr[0, [1]]
Out[173]: array([1])
In [174]: marr[0, 0:1]
Out[174]: array([0])
计数 []
以确定维度。
我正在通过 YouTube 教程学习 numpy。在一段视频中,他证明了
wine_data_arr[:, 0].shape
其中 wine_data_arr
是从 sklearn
导入的二维 numpy 数组。结果是(178,)
,他说“是一维数组”。但是在数学中,例如这个
[1,2,3]
可以表示一个 1×3 的矩阵,其维度为 2
。所以我的问题是为什么 wine_data_arr[:, 0]
是一维数组?我想这个定义在某些情况下一定有用。那么那情况是怎样的呢?
尝试更具体:在编写 wine_data_arr[:, 0]
时,我提供了 两个 参数,即 :
和 0
,结果是 一个维度。当我写wine_data_arr[:, (0,4)]
时,我仍然提供两个参数:
和(0,4)
,一个元组,结果是两个维度。为什么不都产生二维矩阵?
简短的回答:这是约定。
在深入细节之前,让我澄清一下,例如,NumPy 中的“维数”与数学中的“维数”不同。在数学中,[1, 2, 3]
是一个 three-dimensional 向量,如果需要,也可以是一维矩阵。然而,这里的维数实际上是指数组的“物理”维度,即数组(或矩阵,或张量等)中存在多少个轴。
现在让我回到您的问题,即为什么“这个”特定的数组维度定义有帮助。我接下来要说的有点哲学意义,是我自己的看法。从本质上讲,这一切都归结为程序员之间的交流。例如,当你正在阅读一些 Python 代码的文档并且想知道输出数组的维数时,确定文档可以写“N x M x ...”然后仔细定义什么 N,M 等。 是。但在许多情况下,仅轴数(或 NumPy 中提到的“维数”)可能足以告知您。在这种情况下,文档变得更加清晰易读,同时提供了有关预期结果的足够信息。
即使它们“看起来”相同,向量也与矩阵不同。考虑:
>>> np.array([1,2,3,4])
array([1, 2, 3,4])
>>> np.matrix([1,2,3,4])
matrix([[1, 2, 3,4]])
>>> np.matrix([[1,2],[3,4]])
matrix([[1, 2],
[3, 4]])
当像
那样对 two-dimensional 数组进行切片时>>> wine_data_arr = np.array([[1,2,3], [4,5,6], [7,8,9]])
>>> wine_data_arr
array([[1, 2, 3],
[4, 5, 6],
[7, 8, 9]])
您可以使用整数索引请求 lower-dimensional 组件(单个行或列)
>>> wine_data_arr[:,0]
array([1, 4, 7])
>>> wine_data_arr[0,:]
array([1, 2, 3])
或 same-dimensional 使用切片索引的“片段”:
>>> wine_data_arr[:, 0:1]
array([[1],
[4],
[7]])
如果您使用 两个 整数索引,您将得到数组的单个 zero-dimensional 元素:
>>> wine_data_arr[0,0]
1
在 numpy
中,数组可以有 0、1、2 或更多维度。与 MATLAB 相比,没有 2d 下边界。此外 numpy
在显示和索引方面与 Python 列表基本一致。 MATLAB 通常遵循线性代数约定,但我确信数组和向量还有其他数学定义。在物理学中 vector
表示 space 中的一个点或一个方向,而不是 2d 'column vector' 或 'row vector'.
列表:
In [159]: alist = [1, 2, 3]
In [160]: len(alist)
Out[160]: 3
由这个列表组成的数组:
In [161]: arr = np.array(alist)
In [162]: arr.shape
Out[162]: (3,)
索引列表会移除一层嵌套。对数组进行标量索引会删除一个维度。参见
https://numpy.org/doc/stable/user/basics.indexing.html
In [163]: alist[0]
Out[163]: 1
In [164]: arr[0]
Out[164]: 1
一个二维数组:
In [166]: marr = np.arange(4).reshape(2, 2)
In [167]: marr
Out[167]:
array([[0, 1],
[2, 3]])
同样,标量索引删除了一个维度:
In [169]: marr[0,:]
Out[169]: array([0, 1])
In [170]: marr[:, 0]
Out[170]: array([0, 2])
In [172]: marr[1, 1]
Out[172]: 3
使用列表或切片建立索引保留维度:
In [173]: marr[0, [1]]
Out[173]: array([1])
In [174]: marr[0, 0:1]
Out[174]: array([0])
计数 []
以确定维度。