在Python中合并不同大小的数组

时间:2017-03-10 16:57:55

标签: python arrays numpy

有一种简单的方法可以将n个光谱(即形状的数组(y_n,2))和不同长度的y_n合并成一个形状(y_n_max,2 * x)的数组(或列表),方法是填充y_n如果是,则为零

基本上我想让所有光谱彼此相邻。 例如

a = [[1,2],[2,3],[4,5]]
b = [[6,7],[8,9]]

c = [[1,2,6,7],[2,3,8,9],[4,5,0,0]]

数组或列表都可以。我想这归结为用零填充数组?

4 个答案:

答案 0 :(得分:4)

如果你正在处理原生Python列表,那么你可以这样做:

from itertools import zip_longest

c = [a + b for a, b in zip_longest(a, b, fillvalue=[0, 0])]

答案 1 :(得分:2)

您也可以使用extendzip执行此操作,但itertools提供的a始终会超过b。如果b可能超过a,那么您也可以添加一些逻辑。

a = [[1,2],[2,3],[4,5]]
b = [[6,7],[8,9]]

b.extend([[0,0]]*(len(a)-len(b)))
[[x,y] for x,y in zip(a,b)]

答案 2 :(得分:2)

尝试将其他解决方案概括为多个列表:

In [114]: a
Out[114]: [[1, 2], [2, 3], [4, 5]]
In [115]: b
Out[115]: [[6, 7], [8, 9]]
In [116]: c
Out[116]: [[3, 4]]
In [117]: d
Out[117]: [[1, 2], [2, 3], [4, 5], [6, 7], [8, 9]]
In [118]: ll=[a,d,c,b]

zip_longest pad

In [120]: [l for l in itertools.zip_longest(*ll,fillvalue=[0,0])]
Out[120]: 
[([1, 2], [1, 2], [3, 4], [6, 7]),
 ([2, 3], [2, 3], [0, 0], [8, 9]),
 ([4, 5], [4, 5], [0, 0], [0, 0]),
 ([0, 0], [6, 7], [0, 0], [0, 0]),
 ([0, 0], [8, 9], [0, 0], [0, 0])]

intertools.chain展平内部列表(或.from_iterable(l)

In [121]: [list(itertools.chain(*l)) for l in _]
Out[121]: 
[[1, 2, 1, 2, 3, 4, 6, 7],
 [2, 3, 2, 3, 0, 0, 8, 9],
 [4, 5, 4, 5, 0, 0, 0, 0],
 [0, 0, 6, 7, 0, 0, 0, 0],
 [0, 0, 8, 9, 0, 0, 0, 0]]

Convert Python sequence to NumPy array, filling missing values

的更多想法

根据此案例调整@Divakar's解决方案:

def divakars_pad(ll):
    lens = np.array([len(item) for item in ll])
    mask = lens[:,None] > np.arange(lens.max())
    out = np.zeros((mask.shape+(2,)), int)
    out[mask,:] = np.concatenate(ll)
    out = out.transpose(1,0,2).reshape(5,-1)
    return out

In [142]: divakars_pad(ll)
Out[142]: 
array([[1, 2, 1, 2, 3, 4, 6, 7],
       [2, 3, 2, 3, 0, 0, 8, 9],
       [4, 5, 4, 5, 0, 0, 0, 0],
       [0, 0, 6, 7, 0, 0, 0, 0],
       [0, 0, 8, 9, 0, 0, 0, 0]])

对于这么小的尺寸,itertools解决方案更快,即使增加了对阵列的转换。

以数组作为目标,我们不需要chain flattener; reshape负责照顾:

In [157]: np.array(list(itertools.zip_longest(*ll,fillvalue=[0,0]))).reshape(-1, len(ll)*2)
Out[157]: 
array([[1, 2, 1, 2, 3, 4, 6, 7],
       [2, 3, 2, 3, 0, 0, 8, 9],
       [4, 5, 4, 5, 0, 0, 0, 0],
       [0, 0, 6, 7, 0, 0, 0, 0],
       [0, 0, 8, 9, 0, 0, 0, 0]])

答案 3 :(得分:1)

使用zip built-in functionchain.from_iterable function from itertools。与其他发布的解决方案相比,它具有更多类型不可知的好处 - 它只需要您的光谱是可迭代的。

a = [[1,2],[2,3],[4,5]]
b = [[6,7],[8,9]]

c = list(list(chain.from_iterable(zs)) for zs in zip(a,b))

如果您需要2个以上的光谱,可以将zip调用更改为zip(a,b,...)