Supposons que j'ai le code en Python 3
newdata = [[1,6,6],[8,17,25],[2,6,11], [4,6,12]]
Alors comment puis-je générer de manière aléatoire des éléments de données n
(pas très volumineux) qui ne sont pas dans le données
.
Condition: l'élément [a, b, c]
ne doit pas être dans les données
et 0 ,
0 ,
0
[1,3,5]
est bon puisque il n'est pas dans data
et son élément satisfait la condition
[11,3,6]
est mauvais car il ne satisfait pas la condition, 11> 10
Par exemple, lorsque n = 4
, je veux une liste d'éléments qui ne sont pas dupliqués
X, Y, Z = 10, 20, 30 data = [[1,3,6],[8,15,29],[8,9,19]] # observe data
4 Réponses :
Cela a demandé un petit effort, mais cela semble fonctionner:
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)
Cela fonctionne en créant une liste vide, en obtenant une valeur pour n, puis en entrant une boucle d'exactement n itérations. Il crée ensuite une nouvelle liste qui répond aux exigences. Si la nouvelle liste est dans la liste des données observées, elle le fait encore et encore jusqu'à ce qu'elle ne soit pas dans les données. Ensuite, il ajoute ces données à la liste de sortie et répète le processus jusqu'à ce que la boucle for soit interrompue (après n itérations).
Il peut y avoir une meilleure façon de le faire, mais cela fait l'affaire. >
Cela devrait le faire:
newdata = [(9, 9, 11), (10, 10, 4), (7, 6, 23), (2, 10, 4)]
Exemple de résultat:
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)
Cela générera trop peu d'échantillons si l dans les données
car cela rompt néanmoins la boucle. Le break
doit être placé à l'intérieur du bloc if
.
De plus, elle ne traite pas de l'unicité des échantillons générés, c'est-à-dire que cette approche permet les doublons. Cela nécessite une autre vérification je ne suis pas dans les nouvelles données
, donc je vous recommande fortement d'utiliser un ensemble pour les données
et newdata
pour accélérer les tests d'adhésion.
@a_guest, c'est un bon point. Il semble que cette approche autorise les doublons.
@davedwards Vous devez toujours vérifier l not in newdata
également (ou au lieu de la boucle for
do while len (newdata)
données
en un ensemble
avant d'exécuter l'algorithme pour améliorer les tests d'adhésion. Et vous pouvez créer l
comme un tuple
dès le début, ce qui économise une conversion supplémentaire.
Dans le cas où X, Y, Z
ne sont pas trop grands, vous pouvez simplement créer toutes les combinaisons possibles, puis échantillonner à partir de ce 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)
Pour de meilleures performances, vous pouvez utiliser Numpy et le fait que les tuples peuvent être convertis en entier et inversement en les énumérant simplement (comme z, y, x
est énuméré):
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]
Cela semble être un problème intéressant, pouvez-vous également inclure une tentative de codage raisonnable pour commencer?
@davedwards, je pense toujours. Ma méthode consiste à utiliser la technique de la force brute. comme générer tous les éléments possibles, puis sélectionner au hasard les
n
éléments qui ne sont pas dans lesdonnées
. Mais ce n'est pas efficace.Cela pourrait fonctionner, mais oui, la force brute n'est pas toujours efficace. Peut-être quelque chose comme générer
random.randint (0, X)
et vérifier que le résultat n'est pas dans la listedata
, sinon, puis l'ajouter à la liste des nouvelles données?