[英]Randomly generate 1 or -1 (positive or negative integer)
我想在Python
生成1或-1作为在非负数和非正数之间随机化或者随机改变已存在整数的符号的步骤。 在Python
生成1或-1的最佳方法是什么? 假设均匀分布,我知道我可以使用:
import random
#method1
my_number = random.choice((-1, 1))
#method2
my_number = (-1)**random.randrange(2)
#method3
# if I understand correctly random.random() should never return exactly 1
# so I use "<", not "<="
if random.random() < 0.5:
my_number = 1
else:
my_number = -1
#method4
my_number = random.randint(0,1)*2-1
使用timeit
模块我得到以下结果:
#method1
s = "my_number = random.choice((-1, 1))"
timeit.timeit(stmt = s, setup = "import random")
>2.814896769857569
#method2
s = "my_number = (-1)**random.randrange(2)"
timeit.timeit(stmt = s, setup = "import random")
>3.521280517518562
#method3
s = """
if random.random() < 0.5: my_number = 1
else: my_number = -1"""
timeit.timeit(stmt = s, setup = "import random")
>0.25321546903273884
#method4
s = "random.randint(0,1)*2-1"
timeit.timeit(stmt = s, setup = "import random")
>4.526625442240402
所以意外的方法3是最快的。 我打赌方法1是最快的,因为它也是最短的。 方法1(因为Python 3.6
我认为?)和3都提供了引入不均匀分布的可能性。 虽然方法1现在最短(主要优点),但我会选择方法3:
def positive_or_negative():
if random.random() < 0.5:
return 1
else:
return -1
测试:
s = """
import random
def positive_or_negative():
if random.random() < 0.5:
return 1
else:
return -1
"""
timeit.timeit(stmt = "my_number = positive_or_negative()", setup = s)
>0.3916183138621818
在Python
随机生成-1或1的更好(更快或更短)的方法? 你有什么理由选择方法1而不是方法3,反之亦然?
#3的单线间变化:
return 1 if random.random() < 0.5 else -1
它比“数学”变体快(呃),因为它不涉及额外的算术。
这是另一个单行,我的时间显示比if / else比较为0.5更快:
[-1,1][random.randrange(2)]
不确定你的应用程序是什么,但我需要类似的大型矢量化数组。
这是获得符号数组的好方法:
(2 * np.random.randint(0,2,大小=(your_size)) - 1)
结果是一个数组,例如:
数组([ - 1,-1,-1,1,1,1,-1,-1,1,1,1,-1,-1,1,-1])
并且您可以使用reshape命令将上面的内容调整到矩阵的大小:
(2 * np.random.randint(0,2,大小=(m * n个)) - 1).reshape(M,N)
然后你可以用上面的矩阵乘以一个矩阵,并用随机符号得到所有成员。
A = np.array([[1,2,3],[4,5,6]])
B = A *(2 * np.random.randint(0,2,size =(2 * 3)) - 1).reshape(2,3)
然后你会得到类似的东西:
B =数组([[1,2,-3],[4,5,-6]])
非常快,如果您的数据是矢量化的。
如果您需要单个位(每个呼叫一个),您已经完成了基准测试,其他答案提供了额外的信息。
如果您需要很多位或者可以预先计算位数以供以后使用,那么numpy的方法可能会闪耀。
这里有一些使用numpy的演示方法 (令人惊讶的是它没有专门用于此工作的方法):
import numpy as np
import random
def sample_bits(N):
assert N % 8 == 0 # demo only
n_bytes = N // 8
rbytes = np.random.randint(0, 255, dtype=np.uint8, size=n_bytes)
return np.unpackbits(rbytes)
def alt(N):
return np.random.choice([-1,1],size=N)
def alt2(N):
return [1 if random.random() < 0.5 else -1 for i in range(N)]
if __name__ == '__main__':
import timeit
print(timeit.timeit("sample_bits(1024)", setup="from __main__ import sample_bits", number=10000))
print(timeit.timeit("alt(1024)", setup="from __main__ import alt", number=10000))
print(timeit.timeit("alt2(1024)", setup="from __main__ import alt2", number=10000))
输出:
0.06640421246836543
0.352129537507486
1.5522800431775592
一般的想法是:
同样,这只是一个演示:
生成随机数的最快方法是使用numpy:
In [1]: import numpy as np
In [2]: import random
In [3]: %timeit [random.choice([-1,1]) for i in range(100000)]
10 loops, best of 3: 88.9 ms per loop
In [4]: %timeit [(-1)**random.randrange(2) for i in range(100000)]
10 loops, best of 3: 110 ms per loop
In [5]: %timeit [1 if random.random() < 0.5 else -1 for i in range(100000)]
100 loops, best of 3: 18.4 ms per loop
In [6]: %timeit [random.randint(0,1)*2-1 for i in range(100000)]
1 loop, best of 3: 180 ms per loop
In [7]: %timeit np.random.choice([-1,1],size=100000)
1000 loops, best of 3: 1.52 ms per loop
我的代码是
vals = array("i", [-1, 1])
def my_rnd():
return vals[randint(0, 7) % 2]
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.