避免使用numpy.vsplit添加的额外维度

时间:2018-02-09 09:58:14

标签: python numpy

我们可以使用vstack(或hstack)加入多个1d数组,例如D = np.vstack([a,b,c])
反向操作是[a2,b2,c2] = np.vsplit(D, 3)。 但是往返行程的维度会发生变化:

import numpy as np
a = np.random.rand(10,)
b = np.random.rand(10,)
c = np.random.rand(10,)
D = np.vstack([a,b,c])
[a2,b2,c2] = np.vsplit(D, 3)

>>> a.shape
(10,)

>>> a2.shape
(1, 10)

我知道挤压去除尺寸:

>>> a2.squeeze().shape
(10,)

但这很麻烦,特别是在拆分多个阵列时。

有没有办法自动'执行挤压,或控制vsplit的输出以避免尺寸不匹配?

split docs没有提到任何控制输出尺寸的方法,据我所知)

2 个答案:

答案 0 :(得分:1)

你可以尝试:

import numpy as np
a = np.random.rand(10,)
b = np.random.rand(10,)
c = np.random.rand(10,)
D = np.vstack([a,b,c])
[a2,b2,c2]=[D[x,:] for x in range(3)]

print(a2.shape)

输出:

(10,)

答案 1 :(得分:1)

In [98]: D = np.arange(12).reshape(4,3)
In [99]: np.vsplit(D, 4)
Out[99]: 
[array([[0, 1, 2]]),
 array([[3, 4, 5]]),
 array([[6, 7, 8]]),
 array([[ 9, 10, 11]])]

split正在使用切片来选择行,从而保留该维度

[D[i:i+1,:] for i in range(4)]

这是一种允许它返回其他大小分割的一般行为。

但似乎您希望一次返回一行。有很多方法可以做到这一点:

迭代地应用squeeze很容易(而且价格也不贵,因为split已经在迭代):

In [100]: [np.squeeze(x) for x in np.vsplit(D, 4)]
Out[100]: [array([0, 1, 2]), array([3, 4, 5]), array([6, 7, 8]), array([ 9, 10, 11])]

或者您可以使用普通列表理解:

In [101]: [x for x in D]
Out[101]: [array([0, 1, 2]), array([3, 4, 5]), array([6, 7, 8]), array([ 9, 10, 11])]

或者将数组转换为列表(这与D.tolist()不同:

In [102]: list(D)
Out[102]: [array([0, 1, 2]), array([3, 4, 5]), array([6, 7, 8]), array([ 9, 10, 11])]

或按索引迭代。这与split类似,但使用标量索引而不是切片。理解D[i,:]D[i:i+1, :]之间的区别很好。

In [103]: [D[i] for i in range(4)]
Out[103]: [array([0, 1, 2]), array([3, 4, 5]), array([6, 7, 8]), array([ 9, 10, 11])]

由于您正在使用解包,因此您不需要任何此类内容。解包将为您执行行'迭代':

In [106]: a,b,c,d = D
In [107]: a,b,c,d
Out[107]: (array([0, 1, 2]), array([3, 4, 5]), array([6, 7, 8]), array([ 9, 10, 11]))