Reputation: 2106
Assume I have the code in Python 3
X, Y, Z = 10, 20, 30
data = [[1,3,6],[8,15,29],[8,9,19]] # observe data
Then how can I random generate n
(not very large) data elements that are not in the data
.
Condition: the element [a,b,c]
must be not in data
and 0<a<X
, 0<b<Y
, 0<c<Z
[1,3,5]
is good since it is not in data
and its element satisfy the Condition
[11,3,6]
is bad since it does not satisfy the Condition, 11>10
For example, when n=4
, I want a list of element that are not duplicate
newdata = [[1,6,6],[8,17,25],[2,6,11], [4,6,12]]
Upvotes: 2
Views: 75
Reputation: 8047
This should do it:
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)
Example result:
newdata = [(9, 9, 11), (10, 10, 4), (7, 6, 23), (2, 10, 4)]
Upvotes: 1
Reputation: 36299
For higher performance you can use Numpy and the fact that the tuples can be converted to integer and back by simply enumerating them (as z, y, x
gets enumerated):
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]
Upvotes: 0
Reputation: 36299
In case X, Y, Z
are not too large you can just create all possible combinations and then sample from this pool:
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)
Upvotes: 0
Reputation: 51
It took a small effort, but this seems to work:
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)
This works by creating an empty list, getting a value for n, then entering a loop of exactly n iterations. It then creates a new list that satisfies the requirements. If the new list is in the observed data list, it just does it again and again until it isn't in the data. Then it adds this data to the output list and repeats the process until the for loop breaks (after n iterations).
There may be a better way of doing it, but this does the trick.
Upvotes: 0