我写代码,效率很重要。 实际上我需要二维数组,我在 for 循环中填充 0 和 1。什么更好,为什么?
创建空数组并用“0”和“1”填充它。这是伪代码,我的数组会更大。
用零填充数组并使用 if(),如果不为零 - 则添加 1。
所以我需要信息什么是更有效率: 1.将每个元素“0”和“1”放入空数组 或者 2. 制作if()('if'的效率),然后只放入“1”元素。
我会选择zeros()。无论如何,性能瓶颈将是你的 python for 循环。
幸运的是,Numpy 现在作为一个 JIT 编译器,它可以将你糟糕而缓慢的 python for 循环转换为机器代码:
我试过了。它的边缘有点粗糙,但与裸 Python 代码相比,加速效果相当惊人。当然,最好的选择是使用 numpy 进行矢量化,但你并不总是有选择。
Ae = np.empty(10000)
A0 = np.zeros((10000)
最初分配内存的方式略有不同。 但如果你继续做类似的事情,时间上的任何差异都会很小
for i in range(10000):
Ae[i] = <some calc>
或
for i in range(10000):
val = <some calc>
if val>0:
A0[i] = val
如果我必须像这样循环,我会继续使用
np.zeros
,并使用无条件赋值。 它使代码更简单,并且与正在发生的所有其他事情相比,时间差异将很小。
采样次数:
In [33]: def foo0(N):
...: A = np.empty(N,int)
...: for i in range(N):
...: A[i] = np.random.randint(0,2)
...: return A
...:
In [34]: def foo1(N):
...: A = np.zeros(N,int)
...: for i in range(N):
...: val = np.random.randint(0,2)
...: if val:
...: A[i] = val
...: return A
...:
分配 10 0/1 值的 3 种方法
In [35]: foo0(10)
Out[35]: array([0, 0, 1, 0, 0, 1, 0, 1, 1, 0])
In [36]: foo1(10)
Out[36]: array([0, 1, 1, 1, 1, 1, 1, 1, 0, 0])
In [37]: np.random.randint(0,2,10)
Out[37]: array([0, 1, 1, 0, 1, 1, 1, 0, 0, 1])
次:
In [38]: timeit foo0(1000)
100 loops, best of 3: 4.06 ms per loop
In [39]: timeit foo1(1000)
100 loops, best of 3: 3.95 ms per loop
In [40]: timeit np.random.randint(0,2,1000)
... cached.
100000 loops, best of 3: 13.6 µs per loop
2个循环时间几乎相同。
最好创建零数组并使用 if-else 填充它。即使条件会使您的代码变慢,重塑空数组或将其与新向量连接,每次循环迭代的操作都会更慢,因为每次创建新大小的新数组时,都会将旧数组与新向量值一起复制到那里。
在大多数情况下,
np.empty()
和np.zeros()
之间没有显着的性能差异
但是,由于将分配的内存初始化为零的额外步骤,
np.zeros()
可能会稍微慢一些:2 * O(n)