创建没有固定第二维的3D numpy.ndarray
Posted
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了创建没有固定第二维的3D numpy.ndarray相关的知识,希望对你有一定的参考价值。
有时,诸如语音数据之类的数据具有已知数量的观测值(n),未知持续时间和已知数量的测量值(k)。
在NumPy中的2D情况下,很清楚具有已知数量的观测值(n)和未知持续时间的数据如何用形状为(n, )
的ndarray表示。例如:
import numpy as np
x = np.array([ [ 1, 2 ],
[ 1, 2, 3 ]
])
print(x.shape) ### Returns: (2, )
在NumPy中是否存在相当于3D的情况,我们可以在其中形成ndarray
形状(n, , k)
?我能想到的最好的替代方案是拥有形状ndarray
的2D (n, )
,并且每个元素也是具有(k, )
的(转置)形状的2D。例如,
import numpy as np
x = np.array([ [ [1,2], [1,2] ],
[ [1,2], [1,2], [1,2] ]
])
print(x.shape) ### Returns: (2, ); Desired: (2, , 2)
理想情况下,解决方案能够告诉我们ndarray
的维度属性,而无需递归调用(可能替代shape
?)。
你似乎误解了(2,)
的形状意味着什么。这并不意味着(2, <unknown>)
;逗号不是2
和某种空白维度之间的分隔符。 (2,)
是单元素元组的Python语法,其中一个元素是2
。 Python使用这种语法,因为(2)
意味着整数2
,而不是元组。
您没有创建具有任意长度的第二维的二维数组。您正在创建一个对象dtype的一维数组。它的元素是普通的Python列表。像这样的数组与NumPy中几乎所有有用的东西都不兼容。
没有办法创建具有可变长度尺寸的NumPy数组,无论是在您认为有效的2D情况下,还是在您尝试工作的3D情况下。
仅查看1d案例:
In [33]: x = np.array([[1,2],[1,2,3]])
In [34]: x.shape
Out[34]: (2,)
In [35]: x
Out[35]: array([list([1, 2]), list([1, 2, 3])], dtype=object)
结果是一个2元素的列表数组,其中我们从列表列表开始。差别不大。
但请注意,如果列表大小相同,np.array
会创建一个数字2d数组:
In [36]: x = np.array([[1,2,4],[1,2,3]])
In [37]: x
Out[37]:
array([[1, 2, 4],
[1, 2, 3]])
所以不要指望我们在[33]中看到的行为。
我可以创建一个2d对象数组:
In [59]: x = np.empty((2,2),object)
In [60]: x
Out[60]:
array([[None, None], # in this case filled with None
[None, None]], dtype=object)
我可以为每个元素分配不同种类和大小的对象:
In [61]: x[0,0] = np.arange(3)
In [62]: x[0,0] = [1,2,3]
In [63]: x[1,0] = 'abc'
In [64]: x[1,1] = np.arange(6).reshape(2,3)
In [65]: x
Out[65]:
array([[list([1, 2, 3]), None],
['abc', array([[0, 1, 2],
[3, 4, 5]])]], dtype=object)
它仍然是2d。在大多数情况下,它就像包含对象的列表或列表列表。数据缓冲区实际上有指向存储在其他地方的对象的指针(就像列表缓冲区那样)。
实际上不存在具有可变最后维度的3d数组。充其量我们可以得到一个包含各种大小的列表或数组的二维数组。
列出2个2d数组:
In [69]: alist = [np.arange(6).reshape(2,3), np.arange(4.).reshape(2,2)]
In [70]: alist
Out[70]:
[array([[0, 1, 2],
[3, 4, 5]]), array([[0., 1.],
[2., 3.]])]
在这种情况下,将它赋予np.array
会引发错误:在[71]中:np.array(alist)
-------------------------------------------------- ------------------------- ValueError:无法将形状(2,3)的输入数组广播为形状(2)
我们可以使用此列表中的元素填充对象数组:
In [72]: x = np.empty((4,),object)
In [73]: x[0]=alist[0][0]
In [74]: x[1]=alist[0][1]
In [75]: x[2]=alist[1][0]
In [76]: x[3]=alist[1][1]
In [77]: x
Out[77]:
array([array([0, 1, 2]), array([3, 4, 5]), array([0., 1.]),
array([2., 3.])], dtype=object)
并重塑为2d
In [78]: x.reshape(2,2)
Out[78]:
array([[array([0, 1, 2]), array([3, 4, 5])],
[array([0., 1.]), array([2., 3.])]], dtype=object)
结果是包含1d数组的2d数组。要获得元素的形状,我必须做以下事情:
In [87]: np.frompyfunc(lambda i:i.shape, 1,1)(Out[78])
Out[87]:
array([[(3,), (3,)],
[(2,), (2,)]], dtype=object)
以上是关于创建没有固定第二维的3D numpy.ndarray的主要内容,如果未能解决你的问题,请参考以下文章
Pandas 多索引 DataFrame 到 Numpy Ndarray