x和y的范围是0到99。
我目前正在这样做:
excludeFromTrainingSet = []
while len(excludeFromTrainingSet) < 4000:
tempX = random.randint(0, 99)
tempY = random.randint(0, 99)
if [tempX, tempY] not in excludeFromTrainingSet:
excludeFromTrainingSet.append([tempX, tempY])
但这需要很长时间,我真的需要加快速度。
有什么想法吗?
答案 0 :(得分:6)
Vincent Savard的answer速度几乎是此处提供的第一个解决方案的两倍。
这是我的看法。它需要元组而不是可靠性列表:
def method2(size):
ret = set()
while len(ret) < size:
ret.add((random.randint(0, 99), random.randint(0, 99)))
return ret
确保限制是正确的,正如其他回答者所指出的那样。对于合理的输入,这是更好的算法O(n)而不是O(n ^ 2),因为set而不是list。另外,python在加载locals方面要比globals更有效,所以总是把这些东西放在一个函数中。
编辑:实际上,由于概率分量,我不确定它们分别是O(n)和O(n ^ 2)但是如果将n作为它们的唯一元素的数量,则估计是正确的看到。当它们接近可用空间的总数时,它们都会变慢。如果你想要一个接近可用总数的点数,那么最好使用:import random
import itertools
def method2(size, min_, max_):
range_ = range(min_, max_)
points = itertools.product(range_, range_)
return random.sample(list(points), size)
这将是一个记忆力,但随着点密度的增加肯定会更快,因为它避免了多次查看同一点。另一个值得分析的选项(可能比上一个更好)将是
def method3(size, min_, max_):
range_ = range(min_, max_)
points = list(itertools.product(range_, range_))
N = (max_ - min_)**2
L = N - size
i = 1
while i <= L:
del points[random.randint(0, N - i)]
i += 1
return points
答案 1 :(得分:4)
我确定有人会使用numpy进入这里,但是如何使用set和tuple? E.g:
excludeFromTrainingSet = set()
while len(excludeFromTrainingSet) < 40000:
temp = (random.randint(0, 99), random.randint(0, 99))
if temp not in excludeFromTrainingSet:
excludeFromTrainingSet.add(temp)
编辑:这不是一个无限循环,因为只有100 ^ 2 = 10000个可能的结果,你等到40000?
答案 2 :(得分:4)
我的建议:
def method2(size):
randints = range(0, 100)
excludeFromTrainingSet = set()
while len(excludeFromTrainingSet) < size:
excludeFromTrainingSet.add((random.choice(randints), random.choice(randints)))
return excludeFromTrainingSet
不是每次生成2个随机数,而是首先生成0到99之间的数字列表,然后选择2并附加到列表中。正如其他人指出的那样,只有10 000种可能性,所以你不能循环直到你获得4万,但你明白了。
答案 3 :(得分:4)
列出所有可能的(x,y)值:
allpairs = list((x,y) for x in xrange(99) for y in xrange(99))
# or with Py2.6 or later:
from itertools import product
allpairs = list(product(xrange(99),xrange(99)))
# or even taking DRY to the extreme
allpairs = list(product(*[xrange(99)]*2))
随机播放列表:
from random import shuffle
shuffle(allpairs)
读取第一个'n'值:
n = 4000
trainingset = allpairs[:n]
这在我的笔记本电脑上非常不稳定。
答案 4 :(得分:1)
您可以创建一个随机值的查找表...在该查找表中创建一个随机索引,然后使用静态增量计数器逐步执行...
答案 5 :(得分:1)
生成 4万数字不可避免地需要一段时间。但是您正在对excludeFromTrainingSet执行O(n)线性搜索,这需要花费很长时间,尤其是在此过程的后期。改用一套。您还可以考虑生成许多坐标集,例如过夜并腌制它们,因此您不必为每次测试运行生成新数据(不知道您正在做什么,所以这可能会或可能没有帮助)。正如有人所指出的,使用元组不仅是语义上正确的选择,它还可能有助于提高性能(元组创建比列表创建更快)。编辑:愚蠢我,在使用集合时使用元组必需,因为集成员必须是可散列的,列表是不可删除的。
但是在你的情况下,你的循环没有终止,因为0..99是100个数字,而它们的两个元组只有100 ^ 2 = 10000个唯一组合。修复此问题,然后应用上述内容。
答案 6 :(得分:0)
采取Vince Savard的代码:
>>> from random import choice
>>> def method2(size):
... randints = range(0, 100)
... excludeFromTrainingSet = set()
... while True:
... x = size - len(excludeFromTrainingSet)
... if not x:
... break
... else:
... excludeFromTrainingSet.add((choice(randints), choice(randints)) for _ in range(x))
... return excludeFromTrainingSet
...
>>> s = method2(4000)
>>> len(s)
4000
这不是一个很好的算法,因为它必须处理冲突,但是元组生成使它可以容忍。这在我的笔记本电脑上运行大约一秒钟。
答案 7 :(得分:0)
## for py 3.0+
## generate 4000 points in 2D
##
import random
maxn = 10000
goodguys = 0
excluded = [0 for excl in range(0, maxn)]
for ntimes in range(0, maxn):
alea = random.randint(0, maxn - 1)
excluded[alea] += 1
if(excluded[alea] > 1): continue
goodguys += 1
if goodguys > 4000: break
two_num = divmod(alea, 100) ## Unfold the 2 numbers
print(two_num)