假设我拥有Python 3中的代码
X, Y, Z = 10, 20, 30
data = [[1,3,6],[8,15,29],[8,9,19]] # observe data
然后,如何随机生成不在n
中的data
(不是很大)数据元素。
条件:元素[a,b,c]
不能位于data
和0<a<X
,0<b<Y
,0<c<Z
[1,3,5]
很好,因为它不在data
中,并且其元素满足条件
[11,3,6]
很糟糕,因为它不满足条件11>10
例如,当n=4
时,我想要一个不重复的元素列表
newdata = [[1,6,6],[8,17,25],[2,6,11], [4,6,12]]
答案 0 :(得分:1)
这应该做到:
from random import randint
X, Y, Z = 10, 20, 30
data = [[1,3,6],[8,15,29],[8,9,19]]
n = 4
newdata = set()
for i in range(n):
while True:
l = [randint(1, X), randint(1, Y), randint(1, Z)]
if l not in data:
newdata.add(tuple(l))
break
print(newdata)
示例结果:
newdata = [(9, 9, 11), (10, 10, 4), (7, 6, 23), (2, 10, 4)]
答案 1 :(得分:0)
花了一点功夫,但这似乎奏效了:
from random import *
from pprint import pprint
X, Y, Z = 10, 20, 30
data = [[1,3,6],[8,15,29],[8,9,19]]
while 1:
newData = []
try: n = int(input("How many lists do you want: "))
except:
print("Please enter an integer.\n")
continue
for i in range(n):
newList = [randrange(1, X), randrange(1, Y), randrange(1, Z)]
while (newList in data) or (newList in newData):
newList = [randrange(1, X), randrange(1, Y), randrange(1, Z)]
newData.append(newList)
pprint(newData)
通过创建一个空列表,获取n的值,然后输入正好n次迭代的循环来工作。然后,它将创建一个满足要求的新列表。如果新列表位于观察到的数据列表中,它将一次又一次地执行直到它不在数据中为止。然后将这些数据添加到输出列表中,并重复该过程,直到for循环中断(n次迭代后)为止。
也许有更好的方法,但这确实有用。
答案 2 :(得分:0)
如果X, Y, Z
不太大,您可以创建所有可能的组合,然后从该池中采样:
import itertools as it
import random
x, y, z = 10, 20, 30
pool = it.product(range(x), range(y), range(z))
data = [(1, 3, 6), (8, 15, 29), (8, 9, 19)]
pool = set(pool) - set(data)
n = 4
newdata = random.sample(pool, n)
答案 3 :(得分:0)
为了获得更高的性能,您可以使用Numpy,并且可以通过简单地枚举元组(将z, y, x
枚举)将元组转换为整数并返回的事实:
import numpy as np
x, y, z = 100, 200, 300
n = 1000
data = [[1,3,6],[8,15,29],[8,9,19]]
forbidden = [i[0]*y*z + i[1]*z + i[2] for i in data]
pool = np.arange(x*y*z)
mask = np.ones(pool.size, dtype=bool)
mask[forbidden] = False
pool = pool[mask]
newdata = np.random.choice(pool, n, replace=False)
newdata = [(i // (y*z), i // z, i % z) for i in newdata]