为了好玩,我意识到@Lev的原始答案比他的广义编辑更快,所以这是广义堆叠版本,比np.asarray
版本快得多,但不是很优雅。
np.concatenate((a[None,...], b[None,...], c[None,...]), axis=0).argmax(0)
那是:
def bystack(arrs):
return np.concatenate([arr[None,...] for arr in arrs], axis=0).argmax(0)
一些解释:
我为每个数组添加了一个新轴:arr[None,...]
相当于与扩展为适当数字维度arr[np.newaxis,...]
的位置相同。这样做的原因是因为它将沿新维度堆叠,这是因为位于前面。arr[np.newaxis,:,:,:]
...
np.concatenate
0
None
因此,例如:
In [286]: a
Out[286]:
array([[0, 1],
[2, 3]])
In [287]: b
Out[287]:
array([[10, 11],
[12, 13]])
In [288]: np.concatenate((a[None,...],b[None,...]),axis=0)
Out[288]:
array([[[ 0, 1],
[ 2, 3]],
[[10, 11],
[12, 13]]])
如果有助于理解,这也可以:
np.concatenate((a[...,None], b[...,None], c[...,None]), axis=a.ndim).argmax(a.ndim)
现在在末尾添加了新轴,因此我们必须沿最后一个轴堆叠并最大化,这将是a.ndim
. 对于a
、b
和c
2d,我们可以这样做:
np.concatenate((a[:,:,None], b[:,:,None], c[:,:,None]), axis=2).argmax(2)
这相当于dstack
我在上面的评论中提到的(dstack
如果数组中不存在它,则添加第三个轴以堆叠)。
去测试:
N = 10
M = 2
a = np.random.random((N,)*M)
b = np.random.random((N,)*M)
c = np.random.random((N,)*M)
def bystack(arrs):
return np.concatenate([arr[None,...] for arr in arrs], axis=0).argmax(0)
def byarray(arrs):
return np.array(arrs).argmax(axis=0)
def byasarray(arrs):
return np.asarray(arrs).argmax(axis=0)
def bylist(arrs):
assert arrs[0].ndim == 1, "ndim must be 1"
return [np.argmax(x) for x in zip(*arrs)]
In [240]: timeit bystack((a,b,c))
100000 loops, best of 3: 18.3 us per loop
In [241]: timeit byarray((a,b,c))
10000 loops, best of 3: 89.7 us per loop
In [242]: timeit byasarray((a,b,c))
10000 loops, best of 3: 90.0 us per loop
In [259]: timeit bylist((a,b,c))
1000 loops, best of 3: 267 us per loop