将一个包含不同形状的numpy数组的列表展平

4

我正在尝试寻找一种解决方案,以便将以下numpy数组列表平铺:

a = np.arange(9).reshape(3,3)
b = np.arange(25).reshape(5,5)
c = np.arange(4).reshape(2,2)
myarrs = [a,b,c]

d = np.arange(5*5*5).reshape(5,5,5)
myarrs2 = [a,b,c,d]

目前我正在使用的 myarrs :

res = np.hstack([np.hstack(i) for i in myarrs])

但我想知道是否有其他内置方法可以在处理不同形状的数组时执行此任务。 我看到了其他类似的问题:如何展平一个Numpy数组列表?但它们通常是针对具有相同形状的数组。


2
使用np.hstack([i.ravel() for i in myarrs2])可以更高效地实现。因为ravel是一个视图,所以比你现在使用的内部hstack更好。但目前还没有内置的方法。 - Divakar
2个回答

6
你可以尝试像这样做:

你可以尝试像这样做:

np.concatenate([x.ravel() for x in myarrs])

这个方法比你的方法更快:
a = np.arange(9).reshape(3,3)
b = np.arange(25).reshape(5,5)
c = np.arange(4).reshape(2,2)
myarrs = [a,b,c]


res = np.concatenate([x.ravel() for x in myarrs])
print(res)
# [ 0  1  2  3  4  5  6  7  8  0  1  2  3  4  5  6  7  8  9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24  0  1  2  3]


%timeit np.concatenate([x.ravel() for x in myarrs])
# 100000 loops, best of 3: 2.47 µs per loop
%timeit np.concatenate(list(map(lambda x: x.ravel(), myarrs)))
# 100000 loops, best of 3: 2.85 µs per loop
%timeit np.concatenate([x.flatten() for x in myarrs])
# 100000 loops, best of 3: 3.69 µs per loop
%timeit np.hstack([x.ravel() for x in myarrs])
# 100000 loops, best of 3: 5.69 µs per loop
%timeit np.hstack([np.hstack(i) for i in myarrs])
# 10000 loops, best of 3: 29.1 µs per loop

1

我理解您正在寻找仅使用numpy的解决方案。然而,如果允许,还有一种可能性是将more_itertoolsravel()reshape(-1)flatten()一起使用:

>>> import more_itertools
>>> list(more_itertools.flatten(([x.reshape(-1) for x in myarrs])))

对比:

原始解决方案

%timeit -n 100000 np.hstack([np.hstack(i) for i in myarrs])
> 31.6 µs ± 1.16 µs per loop (mean ± std. dev. of 7 runs, 100000 loops each)

norok2提供的解决方案(最快)

%timeit -n 100000 np.concatenate([x.ravel() for x in myarrs])
> 2.62 µs ± 54.6 ns per loop (mean ± std. dev. of 7 runs, 100000 loops each)

使用more_itertools + reshape(-1)的解决方案
%timeit -n 100000 list(more_itertools.flatten(([x.reshape(-1) for x in myarrs])))
> 9.32 µs ± 255 ns per loop (mean ± std. dev. of 7 runs, 100000 loops each)
使用more_itertools+ravel()的解决方案
%timeit -n 100000 list(more_itertools.flatten(([x.ravel() for x in myarrs])))
> 7.33 µs ± 235 ns per loop (mean ± std. dev. of 7 runs, 100000 loops each)

使用more_itertools + flatten()的解决方案
%timeit list(more_itertools.flatten(([x.flatten() for x in myarrs])))
> 8.3 µs ± 65.5 ns per loop (mean ± std. dev. of 7 runs, 100000 loops each)

'list' object has no attribute 'ravel' - seralouk
@seralouk,现在可以请您把负面投票移除掉吗? - Grayrigel
谢谢。我会更加小心地写我的第一个答案。 - Grayrigel
这与 np.concatenate([x.ravel() for x in myarrs]) 相比如何? - norok2
什么意思?你的 np.concatenate 解决方案是最快的。 - Grayrigel
@Grayrigel,如果您在相同的平台上进行more_itertools基于的解决方案基准测试时能提供一下您得到的数字,那将会很有趣。 - norok2

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接