将NumPy数组与其间的指定值连接起来

时间:2015-06-02 08:49:30

标签: python arrays numpy

我想以与hstack相同的方式连接numpy数组。我想在结果中的每个数组之间留一个间隙,比如10

没有循环的任何解决方案?

  

EDIT1

示例是:

arr1=numpy.array([ [1, 2, 3], [4,5,6]])
arr2=numpy.array([ [7, 8, 9], [10,11,12]])

我指定的值为0且差距为5,结果为:

[[1,  2,  3,  0,  0,  0,  0,  0,  4,  5,  6],
 [7,  8,  9,  0,  0,  0,  0,  0, 10, 11, 12]]
  

EDIT2

我需要一个通用的解决方案,要连接的数组可能超过2个

  

EDIT3

数组的宽度,即行数将保持不变,但每个数组的列数可能不同

3 个答案:

答案 0 :(得分:0)

这个怎么样:

np.hstack((arr1, np.zeros((arr1.shape[0], 5)), arr2))

如果你有一个数组列表,你必须以某种方式在调用hstack之前在数组列表中插入零数组。这是一个使用itertools.chain的技巧。但它假设某些内容如数组列表非空,等等。适应您的用例:

from itertools import chain

def hstack_with_zeros(array_list, gap_size):
    shape = array_list[0].shape
    head = list(chain(*[(arr, np.zeros((shape[0], gap_size))) for arr in array_list[:-1]]))
    return np.hstack(head + [array_list[-1]])

示例:

In [10]: hstack_with_zeros([arr1, arr2], 5)
Out[10]:
array([[  1.,   2.,   3.,   0.,   0.,   0.,   0.,   0.,   7.,   8.,   9.],
       [  4.,   5.,   6.,   0.,   0.,   0.,   0.,   0.,  10.,  11.,  12.]])

答案 1 :(得分:0)

这是另一种解决方案,它也提供了指定间隙元素的可能性:

def stackWithGaps(arrays, gap_length, gap_element=0):
    # create the gap
    gap = np.full((arrays[0].shape[0],gap_length), gap_element)

    # see how many elements the stack needs
    n = 2*len(arrays)-1

    # initialize the stack with gaps only
    stack = [gap]*n

    # overwrite every second element with one from the array
    stack[::2] = arrays

    # finally stack our stack
    return np.hstack(stack)

行动中的功能:

In [8]: stackWithGaps([arr1,arr2],5)
Out[8]: 
array([[  1.,   2.,   3.,   0.,   0.,   0.,   0.,   0.,   7.,   8.,   9.],
       [  4.,   5.,   6.,   0.,   0.,   0.,   0.,   0.,  10.,  11.,  12.]])

In [9]: stackWithGaps([arr1,arr2],5,np.nan)
Out[9]: 
array([[  1.,   2.,   3.,  nan,  nan,  nan,  nan,  nan,   7.,   8.,   9.],
       [  4.,   5.,   6.,  nan,  nan,  nan,  nan,  nan,  10.,  11.,  12.]])

答案 2 :(得分:0)

请注意hstack使用迭代:

arrs = [atleast_1d(_m) for _m in tup]
return _nx.concatenate(arrs, 1)

concatenate的所有'cover'函数遍历输入列表,以将数组按到正确的形状。你不应该害怕这种迭代。迭代1000行数组来做一个总和是一回事,在连接之前迭代30个数组的列表是另一回事。

如果您的输入数组都具有相同的列数,则可以在零数组上vstackhstack,并重新整形。但由于您的输入数组可能具有不同数量的列,因此您无法做到这一点。所以你会陷入某种迭代,它会交织零数组。

例如:

构造数组列表:

In [116]: arrs = []
In [117]: for i in range(4):
    arrs.append(np.arange(i,i+2*i).reshape(2,i))

In [122]: pad = np.zeros((2,1))
In [123]: np.concatenate([np.concatenate([i,pad],1) for i in arrs],1)
Out[123]: 
array([[ 0.,  1.,  0.,  2.,  3.,  0.,  3.,  4.,  5.,  0.],
       [ 0.,  2.,  0.,  4.,  5.,  0.,  6.,  7.,  8.,  0.]])

内部concatenate将每个数组填充为零。我首先尝试使用np.pad,但它的输入太复杂了。另外,它最终会使用concatenate

我也可以构建相当于[arr[0], pad, arr[1], pad, ...]的东西,但为了做到这一点,我必须'展平'这个数组:[(i,pad) for i in arrs]

In [132]: ll=[(i,pad) for i in arrs]
In [133]: fl=list(itertools.chain(*ll))  # flatten list of tuples
In [134]: np.concatenate(fl,1)