我是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)。直觉上,我觉得所有阵列都应该是三维的。谁能帮我理解究竟发生了什么?
答案 0 :(得分: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]