繁体   English   中英

扩展4D numpy数组维的最有效方法是什么?

[英]What is the most efficient way to extend a dimension of a 4D numpy array?

例如,假设我有一个形状为(2,3,4,5)的数组,我想向其中添加一个(2,3,4,1)数组以生成一个形状为(2,3, 4,6)。

对于大尺寸,最有效的方法是什么?

有什么比dimshuffle和vstack / hstack / dstack更好的东西吗?

(Python 2.7)

以下是各种方法以及随附的基准:

a = np.zeros([100,200,300,5])
b = np.zeros([100,200,300,1])

%timeit c=np.concatenate([a,b],-1)
#1 loops, best of 3: 241 ms per loop

%timeit c=np.vstack([a.T,b.T]).T
#1 loops, best of 3: 309 ms per loop

%timeit c=np.empty([100,200,300,5]); c[...,:5]=a; c[...,5:]=b
#1 loops, best of 3: 311 ms per loop

# Assuming c was already allocated:
%timeit c[...,:5]=a; c[...,5:]=b
#10 loops, best of 3: 113 ms per loop

这些时间都是相当可比的,而且都很慢。 如果所有数组都按转置顺序排列,我们可以做得更好:

va = np.zeros([5,300,200,100])
vb = np.zeros([1,300,200,100])

%timeit vc=np.concatenate([va,vb],0)
#1 loops, best of 3: 191 ms per loop

%timeit vc=np.vstack([va,vb])
#1 loops, best of 3: 284 ms per loop

%timeit vc=np.empty([6,300,200,100]); vc[:5]=va; vc[5:]=vb
#1 loops, best of 3: 281 ms per loop

#Assuming vc is already allocated. This case is somehow
#much faster than the others!
%timeit vc[:5]=va; vc[5:]=vb
#10 loops, best of 3: 26.4 ms per loop

#Somehow the time for allocating vc and for copying the
#values does not add up. I guess this has to do with
#caching working better when the same buffer is reused
%timeit vc=np.empty([6,300,200,100])
#100000 loops, best of 3: 7.73 µs per loop

在fortran中实现相同的操作并通过f2py调用它只会为未转置案例的分配产生大约55 ms的时间。 因此,这些选项似乎都不是效率极低的。 我建议np.concatenate 它是通用的,由于某种原因,它比等效的*stack稍快。 也就是说,除非您可以预分配和重用输出数组,否则在这种情况下,使用广泛分配的分配至少要快2倍。

使用arr.resize(new_shape=(2,3,4,6)) 这将尝试重新分配原始数组使用的现有内存,因此,它可能比保证返回新分配的数组的任何其他方法快。

缺点是并非总是可以就地执行此操作,在这种情况下,您别无选择,只能创建一个新数组,例如使用numpy.append

在此处进一步阅读有关resize和一些注意事项的信息

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM