Dal*_*lek 1 python numpy matplotlib scipy
如何从包含n元素的列表中随机选择一个数字,n而不选择列表中的相同元素两次。我写了一个代码来选择列表中元素的序列号,但是速度很慢:
>>>redshift=np.array([0.92,0.17,0.51,1.33,....,0.41,0.82])
>>>redshift.shape
(1225,)
exclude=[]
k=0
ng=1225
while (k < ng):
flag1=0
sq=random.randint(0, ng)
while (flag1<1):
if sq in exclude:
flag1=1
sq=random.randint(0, ng)
else:
print sq
exclude.append(sq)
flag1=0
z=redshift[sq]
k+=1
Run Code Online (Sandbox Code Playgroud)
它不会选择列表中元素的所有序列号。
由于您已经在使用 numpy 数组,您不妨使用该包中的工具。
您可以将numpy.random.choice与replace=False. 那只会使用每个元素一次:
>>> redshift=np.array([0.92,0.17,0.51,1.33,0.41,0.82])
>>> np.random.choice(redshift, redshift.size, replace=False)
array([ 0.41, 0.82, 0.17, 1.33, 0.92, 0.51])
Run Code Online (Sandbox Code Playgroud)
由于每个只使用一次,如果您尝试获取超过数组大小的元素,则会出现值错误:
>>> np.random.choice(redshift, redshift.size+1, replace=False)
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
File "mtrand.pyx", line 1051, in mtrand.RandomState.choice (numpy/random/mtrand/mtrand.c:8075)
ValueError: Cannot take a larger sample than population when 'replace=False'
Run Code Online (Sandbox Code Playgroud)
如果您只想将数组(或副本)原地打乱,您也可以使用np.random.shuffle:
>>> redshift
array([ 0.92, 0.17, 0.51, 1.33, 0.41, 0.82])
>>> np.random.shuffle(redshift)
>>> redshift
array([ 0.41, 0.82, 1.33, 0.51, 0.92, 0.17])
Run Code Online (Sandbox Code Playgroud)
请注意,将 numpy 数组保存在 numpy 中比切换回 Python 数据结构来执行诸如获取排序版本之类的操作要快得多:
>>> from timeit import timeit
>>> import random
>>> source=range(1000000)
>>> a=np.array(source)
>>> timeit('np.random.choice(a, a.size, replace=False)', setup='from __main__ import np, a', number=10)
2.971310766064562
>>> timeit('random.sample(list(a), a.size)', setup='from __main__ import random, a', number=10)
14.129850425058976
Run Code Online (Sandbox Code Playgroud)
在这个测试用例中——快了 4 倍以上。