有效的标准基础向量与numpy

时间:2012-08-15 18:40:50

标签: python numpy

给定索引和大小,是否有更有效的方法来生成standard basis vector

import numpy as np
np.array([1.0 if i == index else 0.0 for i in range(size)])

6 个答案:

答案 0 :(得分:15)

In [2]: import numpy as np

In [9]: size = 5

In [10]: index = 2

In [11]: np.eye(1,size,index)
Out[11]: array([[ 0.,  0.,  1.,  0.,  0.]])

不幸的是,嗯,使用np.eye这个很慢:

In [12]: %timeit np.eye(1,size,index)
100000 loops, best of 3: 7.68 us per loop

In [13]: %timeit a = np.zeros(size); a[index] = 1.0
1000000 loops, best of 3: 1.53 us per loop

在函数中包装np.zeros(size); a[index] = 1.0只会产生适度的差异,并且仍然比np.eye快得多:

In [24]: def f(size, index):
   ....:     arr = np.zeros(size)
   ....:     arr[index] = 1.0
   ....:     return arr
   ....: 

In [27]: %timeit f(size, index)
1000000 loops, best of 3: 1.79 us per loop

答案 1 :(得分:7)

x = np.zeros(size)
x[index] = 1.0

至少我认为就是这样......

>>> t = timeit.Timer('np.array([1.0 if i == index else 0.0 for i in range(size)]
)','import numpy as np;size=10000;index=5123')
>>> t.timeit(10)
0.039461429317952934  #original method
>>> t = timeit.Timer('x=np.zeros(size);x[index]=1.0','import numpy as np;size=10000;index=5123')
>>> t.timeit(10)
9.4077963240124518e-05 #zeros method
>>> t = timeit.Timer('x=np.eye(1.0,size,index)','import numpy as np;size=10000;index=5123')
>>> t.timeit(10)
0.0001398340635319073 #eye method

看起来像np.zeros最快...

答案 2 :(得分:6)

我不确定这是否更快,但对我来说肯定更清楚。

a = np.zeros(size)
a[index] = 1.0

答案 3 :(得分:1)

它可能不是最快的,但方法scipy.signal.unit_impulse将上述概念概括为任何形状的numpy数组。

答案 4 :(得分:1)

通常,您不需要一个所有基础向量。如果是这种情况,请考虑np.eye

basis = np.eye(3)
for vector in basis:
  ...

不完全相同,但密切相关:这甚至可以通过一些技巧获得一组基础矩阵:

>>> d, e = 2, 3    # want 2x3 matrices
>>> basis = np.eye(d*e,d*e).reshape((d*e,d,e))
>>> print(basis)
[[[ 1.  0.  0.]
  [ 0.  0.  0.]]

 [[ 0.  1.  0.]
  [ 0.  0.  0.]]

 [[ 0.  0.  1.]
  [ 0.  0.  0.]]

 [[ 0.  0.  0.]
  [ 1.  0.  0.]]

 [[ 0.  0.  0.]
  [ 0.  1.  0.]]

 [[ 0.  0.  0.]
  [ 0.  0.  1.]]]

等等。

答案 5 :(得分:1)

另一种实现方法是:

>>> def f(size, index):
...     return (np.arange(size) == index).astype(float)
... 

哪个执行时间稍慢:

>>> timeit.timeit('f(size, index)', 'from __main__ import f, size, index', number=1000000)
2.2554846050043125