我正在寻找一种更有效地分配 numpy 结构化数组的列的方法。
例子:
my_col = fn_returning_1D_array(...)
在我的机器上执行比对结构化数组的列进行相同分配快两倍以上:
test = np.ndarray(shape=(int(8e6),), dtype=dtype([('column1', 'S10'), ...more columns...]))
test['column1'] = fn_returning_1D_array(...)
我尝试test
使用 fortran 排序进行创建,但没有帮助。据推测,这些字段在内存中保持交错。
有人知道吗?如果可以提供帮助,我愿意使用低级 numpy 接口和 cython。
编辑 1:回应 hpaulj 的回答
仅当以行优先顺序创建后者时,recarray 列分配和“正常”数组列分配的明显等效性才会产生。使用以列为主的排序,这两个分配远非等价:
行专业
In [1]: import numpy as np
In [2]: M,N=int(1e7),10
In [4]: A1=np.zeros((M,N),'f')
In [9]: dt=np.dtype(','.join(['f' for _ in range(N)]))
In [10]: A2=np.zeros((M,),dtype=dt)
In [11]: X=np.arange(M+0.0)
In [13]: %timeit for n in range(N):A1[:,n]=X
1 loops, best of 3: 2.36 s per loop
In [15]: %timeit for n in dt.names: A2[n]=X
1 loops, best of 3: 2.36 s per loop
In [16]: %timeit A1[:,:]=X[:,None]
1 loops, best of 3: 334 ms per loop
In [8]: A1.flags
Out[8]:
C_CONTIGUOUS : True
F_CONTIGUOUS : False
OWNDATA : True
WRITEABLE : True
ALIGNED : True
UPDATEIFCOPY : False
列专业
In [1]: import numpy as np
In [2]: M,N=int(1e7),10
In [3]: A1=np.zeros((M,N),'f', 'F')
In [4]: dt=np.dtype(','.join(['f' for _ in range(N)]))
In [5]: A2=np.zeros((M,),dtype=dt)
In [6]: X=np.arange(M+0.0)
In [8]: %timeit for n in range(N):A1[:,n]=X
1 loops, best of 3: 374 ms per loop
In [9]: %timeit for n in dt.names: A2[n]=X
1 loops, best of 3: 2.43 s per loop
In [10]: %timeit A1[:,:]=X[:,None]
1 loops, best of 3: 380 ms per loop
In [11]: A1.flags
Out[11]:
C_CONTIGUOUS : False
F_CONTIGUOUS : True
OWNDATA : True
WRITEABLE : True
ALIGNED : True
UPDATEIFCOPY : False
请注意,对于列优先排序,两个缓冲区不再相同:
In [6]: A3=np.zeros_like(A2)
In [7]: A3.data = A1.data
In [20]: A2[0]
Out[20]: (0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0)
In [21]: A2[1]
Out[21]: (1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0)
In [16]: A3[0]
Out[16]: (0.0, 1.0, 2.0, 3.0, 4.0, 5.0, 6.0, 7.0, 8.0, 9.0)
In [17]: A3[1]
Out[17]: (10.0, 11.0, 12.0, 13.0, 14.0, 15.0, 16.0, 17.0, 18.0, 19.0)