对于想了解如何为每行用numpyrandom.choice创建2d数组?的读者,本文将提供新的信息,我们将详细介绍创建2行4列的数组arr,并且为您提供关于Numpyrandom.choice仅适用于
对于想了解如何为每行用numpy random.choice创建2d数组?的读者,本文将提供新的信息,我们将详细介绍创建2行4列的数组arr,并且为您提供关于Numpy random.choice 仅适用于小循环,但不适用于更大的循环、numpy.random.choice、numpy.random.rand()/randn()/randint()/normal()/choice()/RandomState()、numpy.random.random & numpy.ndarray.astype & numpy.arange的有价值信息。
本文目录一览:- 如何为每行用numpy random.choice创建2d数组?(创建2行4列的数组arr)
- Numpy random.choice 仅适用于小循环,但不适用于更大的循环
- numpy.random.choice
- numpy.random.rand()/randn()/randint()/normal()/choice()/RandomState()
- numpy.random.random & numpy.ndarray.astype & numpy.arange
如何为每行用numpy random.choice创建2d数组?(创建2行4列的数组arr)
我正在尝试创建一个numpy随机选择的2d数组(由六列和许多行组成),每行的唯一值介于1到50之间,不是数组的全部
np.sort(np.random.choice(np.arange(1,50),size=(100,6),replace=False))
但这会引起错误。
ValueError: Cannot take a larger sample than population when ''replace=False''
有没有可能用一个衬套做到这一点
编辑
好的,我得到了答案。
这些是jupyter%time cellmagic的结果
#@James'' solutionnp.stack([np.random.choice(np.arange(1,50),size=6,replace=False) for i in range(1_000_000)])Wall time: 25.1 s#@Divakar''s solutionnp.random.rand(1_000_000, 50).argpartition(6,axis=1)[:,:6]+1Wall time: 1.36 s#@CoryKramer''s solutionnp.array([np.random.choice(np.arange(1, 50), size=6, replace=False) for _ in range(1_000_000)])Wall time: 25.5 s
我在@Paul Panzer的解决方案上更改了 np.empty和np.random.randint的dtypes ,因为它在我的电脑上不起作用。
3.6.0 |Anaconda custom (64-bit)| (default, Dec 23 2016, 11:57:41) [MSC v.1900 64 bit (AMD64)]
最快的是
def pp(n): draw = np.empty((n, 6), dtype=np.int64) # generating random numbers is expensive, so draw a large one and # make six out of one draw[:, 0] = np.random.randint(0, 50*49*48*47*46*45, (n,),dtype=np.uint64) draw[:, 1:] = np.arange(50, 45, -1) draw = np.floor_divide.accumulate(draw, axis=-1) draw[:, :-1] -= draw[:, 1:] * np.arange(50, 45, -1) # map the shorter ranges (:49, :48, :47) to the non-occupied # positions; this amounts to incrementing for each number on the # left that is not larger. the nasty bit: if due to incrementing # new numbers on the left are "overtaken" then for them we also # need to increment. for i in range(1, 6): coll = np.sum(draw[:, :i] <= draw[:, i, None], axis=-1) collidx = np.flatnonzero(coll) if collidx.size == 0: continue coll = coll[collidx] tot = coll while True: draw[collidx, i] += coll coll = np.sum(draw[collidx, :i] <= draw[collidx, i, None], axis=-1) relidx = np.flatnonzero(coll > tot) if relidx.size == 0: break coll, tot = coll[relidx]-tot[relidx], coll[relidx] collidx = collidx[relidx] return draw + 1#@Paul Panzer'' solutionpp(1_000_000)Wall time: 557 ms
谢谢你们。
答案1
小编典典这是一种有建设性的方法,首先绘制(50个选择),然后绘制(49个选择),等等。对于大集合,这是很有竞争力的(表中的pp):
# n = 10# pp 0.18564210 ms# Divakar 0.01960790 ms# James 0.20074140 ms# CK 0.17823420 ms# n = 1000# pp 0.80046050 ms# Divakar 1.31817130 ms# James 18.93511460 ms# CK 20.83670820 ms# n = 1000000# pp 655.32905590 ms# Divakar 1352.44713990 ms# James 18471.08987370 ms# CK 18369.79808050 ms# pp checking plausibility...# var (exp obs) 208.333333333 208.363840259# mean (exp obs) 25.5 25.5064865# Divakar checking plausibility...# var (exp obs) 208.333333333 208.21113972# mean (exp obs) 25.5 25.499471# James checking plausibility...# var (exp obs) 208.333333333 208.313436938# mean (exp obs) 25.5 25.4979035# CK checking plausibility...# var (exp obs) 208.333333333 208.169585249# mean (exp obs) 25.5 25.49
代码包括基准测试。算法有点复杂,因为映射到自由点很麻烦:
import numpy as npimport typesfrom timeit import timeitdef f_pp(n): draw = np.empty((n, 6), dtype=int) # generating random numbers is expensive, so draw a large one and # make six out of one draw[:, 0] = np.random.randint(0, 50*49*48*47*46*45, (n,)) draw[:, 1:] = np.arange(50, 45, -1) draw = np.floor_divide.accumulate(draw, axis=-1) draw[:, :-1] -= draw[:, 1:] * np.arange(50, 45, -1) # map the shorter ranges (:49, :48, :47) to the non-occupied # positions; this amounts to incrementing for each number on the # left that is not larger. the nasty bit: if due to incrementing # new numbers on the left are "overtaken" then for them we also # need to increment. for i in range(1, 6): coll = np.sum(draw[:, :i] <= draw[:, i, None], axis=-1) collidx = np.flatnonzero(coll) if collidx.size == 0: continue coll = coll[collidx] tot = coll while True: draw[collidx, i] += coll coll = np.sum(draw[collidx, :i] <= draw[collidx, i, None], axis=-1) relidx = np.flatnonzero(coll > tot) if relidx.size == 0: break coll, tot = coll[relidx]-tot[relidx], coll[relidx] collidx = collidx[relidx] return draw + 1def check_result(draw, name): print(name[2:], '' checking plausibility...'') import scipy.stats assert all(len(set(row)) == 6 for row in draw) assert len(set(draw.ravel())) == 50 print('' var (exp obs)'', scipy.stats.uniform(0.5, 50).var(), draw.var()) print('' mean (exp obs)'', scipy.stats.uniform(0.5, 50).mean(), draw.mean())def f_Divakar(n): return np.random.rand(n, 50).argpartition(6,axis=1)[:,:6]+1def f_James(n): return np.stack([np.random.choice(np.arange(1,51),size=6,replace=False) for i in range(n)])def f_CK(n): return np.array([np.random.choice(np.arange(1, 51), size=6, replace=False) for _ in range(n)])for n in (10, 1_000, 1_000_000): print(f''n = {n}'') for name, func in list(globals().items()): if not name.startswith(''f_'') or not isinstance(func, types.FunctionType): continue try: print("{:16s}{:16.8f} ms".format(name[2:], timeit( ''f(n)'', globals={''f'':func, ''n'':n}, number=10)*100)) except: print("{:16s} apparently failed".format(name[2:])) if(n >= 10000): for name, func in list(globals().items()): if name.startswith(''f_'') and isinstance(func, types.FunctionType): check_result(func(n), name)
Numpy random.choice 仅适用于小循环,但不适用于更大的循环
如何解决Numpy random.choice 仅适用于小循环,但不适用于更大的循环?
我正在运行一个 While 循环来执行蒙特卡罗模拟。在循环期间,它调用一个使用 random.choice
的函数def simulate_game(team1,rating1,team2,rating2):
if team2 is ''bye'':
return team1
else :
matchup_arr = [team1,team2]
pteam1 = 1/(1+10**((rating2-rating1)/250))
pteam2 = 1- pteam1
prob_arr = [pteam1,pteam2]
winner = np.random.choice(matchup_arr,size=1,p=prob_arr)
return winner
如果 while 循环运行 1000 次或更少,这工作得很好。但是,如果我尝试运行它,我会收到一个错误,告诉我
''p'' 必须是一维的
有没有想过为什么 random.choice 会有这个问题?...但只有当它连续运行超过 1000 次时
解决方法
暂无找到可以解决该程序问题的有效方法,小编努力寻找整理中!
如果你已经找到好的解决方法,欢迎将解决方案带上本链接一起发送给小编。
小编邮箱:dio#foxmail.com (将#修改为@)
numpy.random.choice
numpy.random.choice
(a, size=None, replace=True, p=None)
从给定的一维数组或整数中生成随机样本
a 一维数组或整数
size 生成样本的大小
replace bool类型 False表示样本中不允许有重复值 True......
p 给定数组中元素出现的概率
例: np.random.choice(5,3,p=[0,0,0,0,1])
output: array([4, 4, 4], dtype=int64)
结果中生成了三个数,因为p中4的概率为1,所以生成的数都为4。
若改为 np.random.choice(5,3,p=[0,0,0,0,1],replace=False)
则会报错,因为size为3,而且只能输出4,所以不允许重复的话无法输出结果
numpy.random.rand()/randn()/randint()/normal()/choice()/RandomState()
这玩意用了很多次,但每次用还是容易混淆,今天来总结mark一下~~~
1. numpy.random.rand(d0,d1,...,dn)
生成一个[0,1)之间的随机数或N维数组
np.random.rand(2) #生成两个[0,1)之间的数
[0.6555729 0.76240372]
np.random.rand(2,2) #生成2行*2列的矩阵
[[0.58360206 0.91619225]
[0.78203671 0.06754087]]
2. numpy.random.randn(d0,d1,...,dn)
生成一个[0,1)之间的随机浮点数或N维浮点数组
正态分布
np.random.randn(2) #生成两个[0,1)之间的浮点数
[-0.03609815 0.25591596]
np.random.randn(2,2) #生成2行*2列的矩阵
[[-0.3021947 -0.37880516]
[-1.84794341 -1.27301629]]
3. numpy.random.randint(low,high=None,size=None,dtype=''1'')
生成一个整数或N维整数数组 若high不为None时,取[low,high)之间随机整数,否则取值[0,low)之间随机整数,且high必须大于low;dtype只能是int类型
np.random.randint(2)#1个0~2的整数
1
np.random.randint(1,2)#1个1~2的整数
1
np.random.randint(1,5,size=3) #3个1~5的整数
[3 1 2]
4.numpy.random.normal(low,high,size=(4,4))
生成一个标准正态分布的4*4样本值
numpy.random.normal(loc=0.0, scale=1, size=(2, 3))
array([[ 2.36637254, -0.28686707, -0.5227531 ],
[ 0.35879566, 0.70202319, -0.84655717]])
5.numpy.random.shuffle()
随机打乱序列 将序列的所有元素随机排序,传入参数可以是一个序列或者元组
[[-0.15040995 -0.43780718 -0.22292445]
[-0.89388124 -0.39465164 0.24113838]]
6.numpy.random.choice()
随机选取序列的一个元素 可以从序列(字符串、列表、元组等)中随机选取,返回一个列表,元组或字符串的随机项
np.random.choice([''a'',''b'',''c'',''d'',''e''])
c
np.random.choice(5, 6)#6个小于5的元素
[2 3 3 3 1 2]
np.random.choice(5, 3, p=[0.1, 0, 0.3, 0.6, 0])#p:每个条目出现的概率。如果没有,假设样本在A中的所有条目都具有均匀分布。
[0 3 2]
7.numpy.random.RandomState()
指定种子值 numpy.random.RandomState()指定种子值(指定种子值是为了使同样的条件下每次产生的随机数一样,避免程序调试时由随机数不同而引起的问题) 如不设置种子值时,np.random.randint(8)可能产生0-7内的任意整数,且每次产生的数字可能是任意一种. 而设置种子值后,np.random.RandomState(0).randint(8)可能产生0-7内的任意整数,但种子值不变时每次运行程序产生的数字一样.
np.random.RandomState(0).randint(8)#产生随机整数
4
n1 = numpy.random.RandomState(0).random_sample()
n2 = numpy.random.RandomState(0).random_sample(size=(2,3))
0.548813503927
[[ 0.5488135 0.71518937 0.60276338]
[ 0.54488318 0.4236548 0.64589411]]
numpy.random.random & numpy.ndarray.astype & numpy.arange
今天看到这样一句代码:
xb = np.random.random((nb, d)).astype(''float32'') #创建一个二维随机数矩阵(nb行d列)
xb[:, 0] += np.arange(nb) / 1000. #将矩阵第一列的每个数加上一个值
要理解这两句代码需要理解三个函数
1、生成随机数
numpy.random.random(size=None)
size为None时,返回float。
size不为None时,返回numpy.ndarray。例如numpy.random.random((1,2)),返回1行2列的numpy数组
2、对numpy数组中每一个元素进行类型转换
numpy.ndarray.astype(dtype)
返回numpy.ndarray。例如 numpy.array([1, 2, 2.5]).astype(int),返回numpy数组 [1, 2, 2]
3、获取等差数列
numpy.arange([start,]stop,[step,]dtype=None)
功能类似python中自带的range()和numpy中的numpy.linspace
返回numpy数组。例如numpy.arange(3),返回numpy数组[0, 1, 2]
我们今天的关于如何为每行用numpy random.choice创建2d数组?和创建2行4列的数组arr的分享已经告一段落,感谢您的关注,如果您想了解更多关于Numpy random.choice 仅适用于小循环,但不适用于更大的循环、numpy.random.choice、numpy.random.rand()/randn()/randint()/normal()/choice()/RandomState()、numpy.random.random & numpy.ndarray.astype & numpy.arange的相关信息,请在本站查询。
本文标签: