我是NumPy / SciPy的新手。从文档中,预分配似乎更有效 单个数组而不是调用append / insert / concatenate。
例如,要向数组添加1的列,我认为:
ar0 = np.linspace(10, 20, 16).reshape(4, 4)
ar0[:,-1] = np.ones_like(ar0[:,0])
比这更受欢迎:
ar0 = np.linspace(10, 20, 12).reshape(4, 3)
ar0 = np.insert(ar0, ar0.shape[1], np.ones_like(ar0[:,0]), axis=1)
我的第一个问题是这是否正确(第一个更好),而我的第二个问题是,目前我只是预先分配我的数组(我在SciPy的几个Cookbook示例中注意到了)位点):
np.zeros((8,5))
“NumPy首选”的方式是什么?
答案 0 :(得分:20)
预分配mallocs在一次调用中需要的所有内存,同时调整数组大小(通过调用append,insert,concatenate或resize)可能需要将数组复制到更大的内存块。所以你是对的,预先分配比调整大小更好(并且应该更快)。
根据您要创建的内容,有许多“首选”方法可以预先分配numpy数组。有np.zeros
,np.ones
,np.empty
,np.zeros_like
,np.ones_like
和np.empty_like
以及其他许多可以创建有用数组的人,例如{{ 1}}和np.linspace
。
所以
np.arange
如果它最接近你想要的ar0 = np.linspace(10, 20, 16).reshape(4, 4)
,那么就好了。
但是,为了使最后一列全部为1,我认为首选的方法是说
ar0
由于ar0[:,-1]=1
的形状为ar0[:,-1]
,因此1为broadcasted以匹配此形状。
答案 1 :(得分:1)
在性能很重要的情况下, np.empty
和 np.zeros
似乎是初始化numpy数组的最快方法。
下面是每种方法的测试结果以及其他一些方法的测试结果。值以秒为单位。
>>> timeit("np.empty(1000000)",number=1000, globals=globals())
0.033749611208094166
>>> timeit("np.zeros(1000000)",number=1000, globals=globals())
0.03421245135849915
>>> timeit("np.arange(0,1000000,1)",number=1000, globals=globals())
1.2212416112155324
>>> timeit("np.ones(1000000)",number=1000, globals=globals())
2.2877375495381145
>>> timeit("np.linspace(0,1000000,1000000)",number=1000, globals=globals())
3.0824269766860652
答案 2 :(得分:0)
根据我的经验,numpy.empty()
是预分配HUGE数组的最快方法。我要说的数组具有(80,80,300000)
和dtype uint8
的形状。
代码如下:
%timeit np.empty((80,80,300000),dtype='uint8')
%timeit np.zeros((80,80,300000),dtype='uint8')
%timeit np.ones((80,80,300000),dtype='uint8')
以及计时结果:
10000 loops, best of 3: 83.7 µs per loop #Too much faster
1 loop, best of 3: 273 ms per loop
1 loop, best of 3: 272 ms per loop