2017-04-05 106 views
0

我想要的是查找2D numpy数组中每列的长度。查找具有不同列长度的numpy数组的形状

如果所有列具有相同的长度,这对numpy.shape来说是微不足道的,但是如果列长度不同,numpy.shape实际上并不告诉我不同​​列的长度。

a=np.asarray([[0,1],[0,1],[0,1]]) 
b=np.asarray([[0,1],[0,1,2],[0]]) 
a.shape,b.shape 
((3,2), (3,)) 

我能得到我想要的相当简单的做这样的事情,

lenb=[len(B) for B in b] 
[2, 3, 1] 

但我觉得必须有一个更清洁,更直接的方式与numpy的做到这一点。

+2

清洁:'map(len,b)'? – Divakar

+3

首先,这些是行。其次,你应该几乎不会尝试像这样创建一个锯齿状的NumPy数组。 NumPy不是为它设计的,索引会中断,广播将会中断,所有的东西和厨房的水槽都会断开......如果你真的需要使用锯齿形的数据结构,不要把它作为一个数组。 – user2357112

回答

2

您的b是一个对象数组 - 带有列表元素的1d。该阵列上的大多数操作都需要列表理解或映射。

array([[0, 1], [0, 1, 2], [0]], dtype=object) 

'object'dtype将数组操作从列表中分离出来。 shape是一个数组属性。 len()是最接近的列表函数,但它必须分别应用于每个元素。

在Py3中,我更喜欢列表理解的清晰度来映射,但这只是一种偏好。在功能上却是同样的事情:

In [30]: [len(i) for i in b] 
Out[30]: [2, 3, 1] 
In [31]: list(map(len,b)) 
Out[31]: [2, 3, 1] 

还有另一种可能性:

In [32]: np.frompyfunc(len,1,1)(b) 
Out[32]: array([2, 3, 1], dtype=object) 

你可以改变的b到其他对象的元素与len

In [39]: b[0]='abcd' # string 
In [43]: b[2]={1,2,1,3,4} # set 
In [44]: b 
Out[44]: array(['abcd', [0, 1, 2], {1, 2, 3, 4}], dtype=object) 
In [45]: [len(i) for i in b] 
Out[45]: [4, 3, 4] 

这应该突出显示len是一个属性的事实元素,而不是数组或它的'列'(它没有)。