我在NumPy中有一个1D数组,它隐式地表示行主要顺序的一些2D数据。这是一个简单的例子:
import numpy as np
# My data looks like [[1,2,3,4], [5,6,7,8]]
a = np.array([1,2,3,4,5,6,7,8])
我想以列主要顺序获得一维数组(即上例中的b = [1,5,2,6,3,7,4,8]
)。
通常,我会做以下事情:
mat = np.reshape(a, (-1,4))
b = mat.flatten('F')
不幸的是,我的输入数组的长度并不是我想要的行长度的精确倍数(即。a = [1,2,3,4,5,6,7]
),所以我无法调用reshape
。我想保留那些额外的数据,这可能是因为我的行很长。在NumPy中有没有直接的方法呢?
答案 0 :(得分:2)
我能想到的最简单的方法是不尝试使用reshape
之类的方法来使用ravel('F')
,但只是为了连接数组的切片视图。
例如:
>>> cols = 4
>>> a = np.array([1,2,3,4,5,6,7])
>>> np.concatenate([a[i::cols] for i in range(cols)])
array([1, 5, 2, 6, 3, 7, 4])
这适用于任何长度的数组和任意数量的列:
>>> cols = 5
>>> b = np.arange(17)
>>> np.concatenate([b[i::cols] for i in range(cols)])
array([ 0, 5, 10, 15, 1, 6, 11, 16, 2, 7, 12, 3, 8, 13, 4, 9, 14])
或者,使用as_strided
重塑。数组a
太小而不适合(2, 4)
形状这一事实并不重要:你最后会得到垃圾(即内存中的任何内容):
>>> np.lib.stride_tricks.as_strided(a, shape=(2, 4))
array([[ 1, 2, 3, 4],
[ 5, 6, 7, 168430121]])
>>> _.flatten('F')[:7]
array([1, 5, 2, 6, 3, 7, 4])
在一般情况下,给定一个数组b
和所需数量的列cols
,您可以这样做:
>>> x = np.lib.stride_tricks.as_strided(b, shape=(len(b)//cols + 1, cols)) # reshape to min 2d array needed to hold array b
>>> np.concatenate((x[:,:len(b)%cols].ravel('F'), x[:-1, len(b)%cols:].ravel('F')))
这解开了数组的“好”部分(那些不包含垃圾值的列)和坏部分(除了位于底行的垃圾值之外)并连接两个未拆分的数组。例如:
>>> cols = 5
>>> b = np.arange(17)
>>> x = np.lib.stride_tricks.as_strided(b, shape=(len(b)//cols + 1, cols))
>>> np.concatenate((x[:,:len(b)%cols].ravel('F'), x[:-1, len(b)%cols:].ravel('F')))
array([ 0, 5, 10, 15, 1, 6, 11, 16, 2, 7, 12, 3, 8, 13, 4, 9, 14])
答案 1 :(得分:1)
使用某个值表示null,使数组成为您想要拆分数的倍数。如果可以接受cast to float,则可以使用nan来表示代表null的添加元素。然后重塑为2D,调用转置,并重塑为1D。然后消除空值。
import numpy as np
a = np.array([1,2,3,4,5,6,7]) # input
b = np.concatenate( (a, [np.NaN]) ) # add a NaN to make it 8 = 4x2
c = b.reshape(2,4).transpose().reshape(8,) # reshape to 2x4, transpose, reshape to 8x1
d = c[-np.isnan(c)] # remove NaN
print d
[ 1. 5. 2. 6. 3. 7. 4.]