numpy:高效执行数组的复形重塑

时间:2011-03-24 16:14:20

标签: python multidimensional-array numpy slice

我正在将供应商提供的大型二进制数组读入2D numpy数组tempfid(M,N)

# load data
data=numpy.fromfile(file=dirname+'/fid', dtype=numpy.dtype('i4'))

# convert to complex data
fid=data[::2]+1j*data[1::2]

tempfid=fid.reshape(I*J*K, N)

然后我需要使用非平凡映射为索引将其重塑为4D数组useful4d(N,I,J,K)。我通过以下几行的for循环执行此操作:

for idx in range(M):
    i=f1(idx) # f1, f2, and f3 are functions involving / and % as well as some lookups
    j=f2(idx)
    k=f3(idx)
    newfid[:,i,j,k] = tempfid[idx,:] #SLOW! CAN WE IMPROVE THIS?

转换为复合体需要33%的时间,而复制这些切片M个切片需要剩余的66%。计算索引是快速的,无论我是在循环中逐个执行,还是通过numpy.vectorizing操作并将其应用于arange(M)。

有没有办法加快速度?任何有关更高效切片,复制(或不复制)等方面的帮助都会受到赞赏。

修改 正如在问题"What's the fastest way to convert an interleaved NumPy integer array to complex64?"的答案中所了解的那样,如果使用视图,则转换为复数可以加速6倍:

 fid = data.astype(numpy.float32).view(numpy.complex64)

2 个答案:

答案 0 :(得分:2)

这个怎么样?使用f1,f2,f3的矢量化版本(不一定使用np.vectorize,但可能只是编写一个接受数组并返回数组的函数)为我们设置你的指标,然后使用np.ix_

http://docs.scipy.org/doc/numpy/reference/generated/numpy.ix_.html

获取索引数组。然后将tempfid重新整形为与newfid相同的形状,然后使用np.ix_的结果来设置值。例如:

tempfid = np.arange(10)
i = f1(idx) # i = [4,3,2,1,0]
j = f2(idx) # j = [1,0]
ii = np.ix_(i,j)
newfid = tempfid.reshape((5,2))[ii]

这会将tempfid的元素映射到具有不同排序的新形状。

答案 1 :(得分:2)

idx = numpy.arange(M)
i = numpy.vectorize(f1)(idx)
j = numpy.vectorize(f2)(idx)
k = numpy.vectorize(f3)(idx)

# you can index arrays with other arrays
# that lets you specify this operation in one line.    
newfid[:, i,j,k] = tempfid.T

我从未使用过numpy的矢量化。 Vectorize只意味着numpy会多次调用你的python函数。为了获得速度,你需要使用像我在这里展示的数组操作,你曾经得到过复杂的数字。

修改

问题是大小128的维度首先在newfid中,但最后在tempfid中。这很容易使用.T进行转置。