创建没有固定第二维的3D numpy.ndarray

时间:2019-04-07 01:13:38

标签: python numpy

有时语音数据之类的数据具有已知的观察次数(n),未知的持续时间和已知的测量次数(k)。

在NumPy中的2D情况下,很清楚如何用形状为(n, )的ndarray表示具有已知观察数(n)和未知持续时间的数据。例如:

import numpy as np

x = np.array([ [ 1, 2 ],
               [ 1, 2, 3 ]
             ])

print(x.shape) ### Returns: (2, )

在NumPy中是否有3D情况的等效项,在这里我们可以拥有形状为ndarray的{​​{1}}?我能想到的最好的替代方法是具有(n, , k)形状的2D ndarray,并使每个元素也是(n, )(转置)形状的2D。例如,

(k, )

理想情况下,解决方案将能够告诉我们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?)。

2 个答案:

答案 0 :(得分:2)

您似乎误解了(2,)的含义。这并不意味着(2, <unknown>);逗号不是2和某种空白尺寸之间的分隔符。 (2,)是一个元素为2的单元素元组的Python语法。 Python使用此语法,因为(2)表示整数2,而不是元组。

您没有创建具有任意长度的第二维的二维数组。您正在创建对象dtype的一维数组。它的元素是普通的Python列表。像这样的数组与NumPy中几乎所有有用的东西都不兼容。

无论是在您认为可行的2D情况下还是在尝试进行工作的3D情况下,都无法创建具有可变长度尺寸的NumPy数组。

答案 1 :(得分:0)

只需审查一维案件:

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)