numpy 零或空数组

问题描述 投票:0回答:4

我写代码,效率很重要。 实际上我需要二维数组,我在 for 循环中填充 0 和 1。什么更好,为什么?

  1. 创建空数组并用“0”和“1”填充它。这是伪代码,我的数组会更大。

  2. 用零填充数组并使用 if(),如果不为零 - 则添加 1。

所以我需要信息什么是更有效率: 1.将每个元素“0”和“1”放入空数组 或者 2. 制作if()('if'的效率),然后只放入“1”元素。

python arrays numpy
4个回答
2
投票
  • empty() 不会初始化内存,因此您的数组将充满垃圾,并且您必须初始化所有单元格。
  • zeros() 将所有内容初始化为 0。因此,如果您的最终结果包含大量零,这将节省您手动将所有这些数组单元设置为零的时间。

我会选择zeros()。无论如何,性能瓶颈将是你的 python for 循环。

幸运的是,Numpy 现在作为一个 JIT 编译器,它可以将你糟糕而缓慢的 python for 循环转换为机器代码:

http://numba.pydata.org/

我试过了。它的边缘有点粗糙,但与裸 Python 代码相比,加速效果相当惊人。当然,最好的选择是使用 numpy 进行矢量化,但你并不总是有选择。


1
投票
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个循环时间几乎相同。


1
投票

最好创建零数组并使用 if-else 填充它。即使条件会使您的代码变慢,重塑空数组或将其与新向量连接,每次循环迭代的操作都会更慢,因为每次创建新大小的新数组时,都会将旧数组与新向量值一起复制到那里。


0
投票

在大多数情况下,

np.empty()
np.zeros()

之间没有显着的性能差异

但是,由于将分配的内存初始化为零的额外步骤,

np.zeros()
可能会稍微慢一些:
2 * O(n)

© www.soinside.com 2019 - 2024. All rights reserved.