了解 ndarray 形状
Understanding ndarray shapes
我是 numpy 的新手,无法理解数组的形状是如何决定的。
形式的数组
[[[5, 10, 15], [20, 25, 30], [35, 40, 45]], [1,2,4,3]]
的形状为 (2,) 而其中一种形式为
[[[5, 10, 15], [20, 25, 30], [35, 40, 45]], [1,2,4]]
的形状为 (2,3)。此外,
[[[5, 10, 15], [20, 25, 30], [35, 40, 45]], [[1,2,4], [3,4,2]]]
具有 (2,) 的形状,但添加另一个向量作为
[[[5, 10, 15], [20, 25, 30], [35, 40, 45]], [[1,2,4], [3,4,2], [1,2,4]]]
将形状更改为 (2,3,3)。直觉上,我觉得所有的数组都应该是3维的。谁能帮助我了解到底发生了什么?
基本思想是 np.array
尝试创建尽可能高的维度数组。当子列表具有匹配数量的元素时,结果很容易看到。当他们混合使用不同长度的列表时,结果可能会令人困惑。
在您的第一种情况下,您有 2 个子列表,一个长度为 3,另一个长度为 4。因此它构成了一个 2 元素对象数组,并且不会尝试解析第一个子列表的子列表
In [1]: arr = np.array([[[5, 10, 15], [20, 25, 30], [35, 40, 45]], [1,2,4,3]])
In [2]: arr
Out[2]: array([[[5, 10, 15], [20, 25, 30], [35, 40, 45]],
[1, 2, 4, 3]
], dtype=object) # adjusted format
In [3]: arr.dtype
Out[3]: dtype('O')
In [4]: arr.shape
Out[4]: (2,)
In [5]: arr[0]
Out[5]: [[5, 10, 15], [20, 25, 30], [35, 40, 45]] # 3 element list of lists
In [6]: arr[1]
Out[6]: [1, 2, 4, 3] # 4 element list of numbers
在第二种情况下,您有两个子列表,长度均为 3。因此它构成了一个 2x3 数组。但是一个子列表包含列表,其他的数字 - 所以结果又是对象数组:
In [7]: arr = np.array([[[5, 10, 15], [20, 25, 30], [35, 40, 45]], [1,2,4]] )
In [8]: arr
Out[8]:
array([[[5, 10, 15], [20, 25, 30], [35, 40, 45]],
[1, 2, 4]
], dtype=object)
In [9]: arr.shape
Out[9]: (2, 3)
In [10]: arr[0,0]
Out[10]: [5, 10, 15]
最后,2 个列表,每个列表有 3 个元素,每个列表也是 3 个元素列表 - 一个 3d 数组。
In [11]: arr = np.array([[[5, 10, 15], [20, 25, 30], [35, 40, 45]], [[1,2,4], [3,4,2], [1,2,4]]] )
In [12]: arr
Out[12]:
array([[[ 5, 10, 15],
[20, 25, 30],
[35, 40, 45]],
[[ 1, 2, 4],
[ 3, 4, 2],
[ 1, 2, 4]]])
In [13]: arr.shape
Out[13]: (2, 3, 3)
子列表长度的混合也可能引发错误。
一般情况下不要随意混合不同大小和内容类型的子列表。 np.array
当给定的列表将生成一个漂亮的多维数组时,其行为最可预测。混合列表长度会导致混乱。
已更新 numpy:
In [1]: np.__version__
Out[1]: '1.13.1'
In [2]: np.array([[[5, 10, 15], [20, 25, 30], [35, 40, 45]], [1,2,4,3]])
Out[2]: array([list([[5, 10, 15], [20, 25, 30], [35, 40, 45]]), list([1, 2, 4, 3])], dtype=object)
In [3]: np.array([[[5, 10, 15], [20, 25, 30], [35, 40, 45]], [1,2,4]] )
Out[3]:
array([[list([5, 10, 15]), list([20, 25, 30]), list([35, 40, 45])],
[1, 2, 4]], dtype=object)
它现在标识 list
个元素
最后这个例子仍然是 (2,3) 对象数组。因此,这 6 个元素中的每一个都可以是不同的 Python 类型,例如:
In [11]: np.array([[[5, 10, 15], np.array([20, 25, 30]), (35, 40, 45)], [None,2,'astr']] )
Out[11]:
array([[list([5, 10, 15]), array([20, 25, 30]), (35, 40, 45)],
[None, 2, 'astr']], dtype=object)
In [12]: [type(x) for x in _.flat]
Out[12]: [list, numpy.ndarray, tuple, NoneType, int, str]
我是 numpy 的新手,无法理解数组的形状是如何决定的。
形式的数组[[[5, 10, 15], [20, 25, 30], [35, 40, 45]], [1,2,4,3]]
的形状为 (2,) 而其中一种形式为
[[[5, 10, 15], [20, 25, 30], [35, 40, 45]], [1,2,4]]
的形状为 (2,3)。此外,
[[[5, 10, 15], [20, 25, 30], [35, 40, 45]], [[1,2,4], [3,4,2]]]
具有 (2,) 的形状,但添加另一个向量作为
[[[5, 10, 15], [20, 25, 30], [35, 40, 45]], [[1,2,4], [3,4,2], [1,2,4]]]
将形状更改为 (2,3,3)。直觉上,我觉得所有的数组都应该是3维的。谁能帮助我了解到底发生了什么?
基本思想是 np.array
尝试创建尽可能高的维度数组。当子列表具有匹配数量的元素时,结果很容易看到。当他们混合使用不同长度的列表时,结果可能会令人困惑。
在您的第一种情况下,您有 2 个子列表,一个长度为 3,另一个长度为 4。因此它构成了一个 2 元素对象数组,并且不会尝试解析第一个子列表的子列表
In [1]: arr = np.array([[[5, 10, 15], [20, 25, 30], [35, 40, 45]], [1,2,4,3]])
In [2]: arr
Out[2]: array([[[5, 10, 15], [20, 25, 30], [35, 40, 45]],
[1, 2, 4, 3]
], dtype=object) # adjusted format
In [3]: arr.dtype
Out[3]: dtype('O')
In [4]: arr.shape
Out[4]: (2,)
In [5]: arr[0]
Out[5]: [[5, 10, 15], [20, 25, 30], [35, 40, 45]] # 3 element list of lists
In [6]: arr[1]
Out[6]: [1, 2, 4, 3] # 4 element list of numbers
在第二种情况下,您有两个子列表,长度均为 3。因此它构成了一个 2x3 数组。但是一个子列表包含列表,其他的数字 - 所以结果又是对象数组:
In [7]: arr = np.array([[[5, 10, 15], [20, 25, 30], [35, 40, 45]], [1,2,4]] )
In [8]: arr
Out[8]:
array([[[5, 10, 15], [20, 25, 30], [35, 40, 45]],
[1, 2, 4]
], dtype=object)
In [9]: arr.shape
Out[9]: (2, 3)
In [10]: arr[0,0]
Out[10]: [5, 10, 15]
最后,2 个列表,每个列表有 3 个元素,每个列表也是 3 个元素列表 - 一个 3d 数组。
In [11]: arr = np.array([[[5, 10, 15], [20, 25, 30], [35, 40, 45]], [[1,2,4], [3,4,2], [1,2,4]]] )
In [12]: arr
Out[12]:
array([[[ 5, 10, 15],
[20, 25, 30],
[35, 40, 45]],
[[ 1, 2, 4],
[ 3, 4, 2],
[ 1, 2, 4]]])
In [13]: arr.shape
Out[13]: (2, 3, 3)
子列表长度的混合也可能引发错误。
一般情况下不要随意混合不同大小和内容类型的子列表。 np.array
当给定的列表将生成一个漂亮的多维数组时,其行为最可预测。混合列表长度会导致混乱。
已更新 numpy:
In [1]: np.__version__
Out[1]: '1.13.1'
In [2]: np.array([[[5, 10, 15], [20, 25, 30], [35, 40, 45]], [1,2,4,3]])
Out[2]: array([list([[5, 10, 15], [20, 25, 30], [35, 40, 45]]), list([1, 2, 4, 3])], dtype=object)
In [3]: np.array([[[5, 10, 15], [20, 25, 30], [35, 40, 45]], [1,2,4]] )
Out[3]:
array([[list([5, 10, 15]), list([20, 25, 30]), list([35, 40, 45])],
[1, 2, 4]], dtype=object)
它现在标识 list
个元素
最后这个例子仍然是 (2,3) 对象数组。因此,这 6 个元素中的每一个都可以是不同的 Python 类型,例如:
In [11]: np.array([[[5, 10, 15], np.array([20, 25, 30]), (35, 40, 45)], [None,2,'astr']] )
Out[11]:
array([[list([5, 10, 15]), array([20, 25, 30]), (35, 40, 45)],
[None, 2, 'astr']], dtype=object)
In [12]: [type(x) for x in _.flat]
Out[12]: [list, numpy.ndarray, tuple, NoneType, int, str]