我需要存储一个大小为n
的数组,其值为cos(x)
和sin(x)
,让我们说
array[[cos(0.9), sin(0.9)],
[cos(0.35),sin(0.35)],
...]
每对cos和sin的论证都是随机选择的。就我一直在改进的情况而言,我的代码是这样的:
def randvector():
""" Generates random direction for n junctions in the unitary circle """
x = np.empty([n,2])
theta = 2 * np.pi * np.random.random_sample((n))
x[:,0] = np.cos(theta)
x[:,1] = np.sin(theta)
return x
是否有更短的方式或更有效的方法来实现这一目标?
答案 0 :(得分:4)
您的代码足够有效。而且我认为justhalf的回答并不差。
为了有效和简短,这段代码怎么样?
def randvector(n):
theta = 2 * np.pi * np.random.random_sample((n))
return np.vstack((np.cos(theta), np.sin(theta))).T
<强>更新强>
附加cProfile结果。
<强> justhalf的强>
5 function calls in 4.707 seconds
Ordered by: standard name
ncalls tottime percall cumtime percall filename:lineno(function)
1 0.001 0.001 4.707 4.707 <string>:1(<module>)
1 2.452 2.452 4.706 4.706 test.py:6(randvector1)
1 0.000 0.000 0.000 0.000 {method 'disable' of '_lsprof.Profiler' objects}
1 0.010 0.010 0.010 0.010 {method 'random_sample' of 'mtrand.RandomState' objects}
1 2.244 2.244 2.244 2.244 {numpy.core.multiarray.array}
<强> OP的强>
5 function calls in 0.088 seconds
Ordered by: standard name
ncalls tottime percall cumtime percall filename:lineno(function)
1 0.000 0.000 0.088 0.088 <string>:1(<module>)
1 0.079 0.079 0.088 0.088 test.py:9(randvector2)
1 0.000 0.000 0.000 0.000 {method 'disable' of '_lsprof.Profiler' objects}
1 0.009 0.009 0.009 0.009 {method 'random_sample' of 'mtrand.RandomState' objects}
1 0.000 0.000 0.000 0.000 {numpy.core.multiarray.empty}
<强>雷强>
21 function calls in 0.087 seconds
Ordered by: standard name
ncalls tottime percall cumtime percall filename:lineno(function)
1 0.000 0.000 0.087 0.087 <string>:1(<module>)
2 0.000 0.000 0.000 0.000 numeric.py:322(asanyarray)
1 0.000 0.000 0.002 0.002 shape_base.py:177(vstack)
2 0.000 0.000 0.000 0.000 shape_base.py:58(atleast_2d)
1 0.076 0.076 0.087 0.087 test.py:17(randvector3)
6 0.000 0.000 0.000 0.000 {len}
1 0.000 0.000 0.000 0.000 {map}
2 0.000 0.000 0.000 0.000 {method 'append' of 'list' objects}
1 0.000 0.000 0.000 0.000 {method 'disable' of '_lsprof.Profiler' objects}
1 0.009 0.009 0.009 0.009 {method 'random_sample' of 'mtrand.RandomState' objects}
2 0.000 0.000 0.000 0.000 {numpy.core.multiarray.array}
1 0.002 0.002 0.002 0.002 {numpy.core.multiarray.concatenate}
答案 1 :(得分:2)
你的代码对我来说已经很好了,但是还有一些想法。
这是一个单行。 它比你的版本略慢。
def randvector2(n):
return np.exp((2.0j * np.pi) * np.random.rand(n, 1)).view(dtype=np.float64)
我得到这些时间为n = 10000
此致:
1000 loops, best of 3: 716 µs per loop
我的缩短版本:
1000 loops, best of 3: 834 µs per loop
现在如果速度是一个问题,你的方法真的非常好。 另一个答案显示了如何使用hstack。 这很好用。 这是另一个与你的版本略有不同的版本,速度稍快。
def randvector3(n):
x = np.empty([n,2])
theta = (2 * np.pi) * np.random.rand(n)
np.cos(theta, out=x[:,0])
np.sin(theta, out=x[:,1])
return x
这给了我时间:
1000 loops, best of 3: 698 µs per loop
如果您可以访问numexpr,则以下内容更快(至少在我的机器上)。
import numexpr as ne
def randvector3(n):
sample = np.random.rand(n, 1)
c = 2.0j * np.pi
return ne.evaluate('exp(c * sample)').view(dtype=np.float64)
这给了我时间:
1000 loops, best of 3: 366 µs per loop
老实说,如果我写这篇文章并不是那些性能不是很高的东西,我会做同样的事情。 它使你的意图对读者非常清楚。 带有hstack的版本也运行良好。
另一个快速说明: 当我运行n = 10的时间时,我的单行版本是最快的。 当我做n = 10000000时,快速纯粹的numpy版本是最快的。
答案 2 :(得分:-2)
您可以使用列表推导使代码更短一点:
def randvector(n):
return np.array([(np.cos(theta), np.sin(theta)) for theta in 2*np.pi*np.random.random_sample(n)])
但是,正如IanH在评论中提到的那样,这个问题比较慢。事实上,通过我的实验,这个速度慢了5倍,因为它没有利用NumPy矢量化。
所以回答你的问题:
有更短的路吗?
是的,这是我在这个答案中给出的内容,虽然它只缩短了几个字符(但它节省了很多行!)
是否更有效(我相信你的意思是&#34;高效&#34;)方式?
我相信这个问题的答案,没有过度复杂的代码,是不行的,因为numpy已经优化了矢量化(将cos和sin值分配给数组)
比较各种方法:
OP&#39; randvector
:0.002131 s
我的randvector
:0.013218 s
mskimm&#39; s randvector
:0.003175 s
所以似乎mskimm的randvector
在代码长度效率方面看起来很好= D