python - array - Mejor manera de barajar dos listas relacionadas
shuffle list c# (6)
¿Hay mejores maneras de mezclar aleatoriamente dos listas relacionadas sin romper su correspondencia en la otra lista? He encontrado preguntas relacionadas en numpy.array
y c#
pero no exactamente la misma.
Como primer intento, un simple truco zip
hará:
import random
a = [[1, 2], [3, 4], [5, 6], [7, 8], [9, 10]]
b = [2, 4, 6, 8, 10]
c = zip(a, b)
random.shuffle(c)
a = [e[0] for e in c]
b = [e[1] for e in c]
print a
print b
Obtendrá la salida:
[[1, 2], [7, 8], [3, 4], [5, 6], [9, 10]]
[2, 8, 4, 6, 10]
Simplemente encontrarlo un poco incómodo Y también necesita una lista adicional también.
Dada la relación demostrada en la pregunta, voy a suponer que las listas tienen la misma longitud y que list1[i]
corresponde a list2[i]
para cualquier índice i
. Con esa suposición en su lugar, barajar las listas es tan simple como barajar los índices:
from random import shuffle
# Given list1 and list2
list1_shuf = []
list2_shuf = []
index_shuf = range(len(list1))
shuffle(index_shuf)
for i in index_shuf:
list1_shuf.append(list1[i])
list2_shuf.append(list2[i])
Hasta ahora, todas las soluciones crearon nuevas listas para resolver el problema. Si las listas a y b son muy largas, es posible que desee barajarlas en su lugar. Para eso necesitarías una función como:
import random
def shuffle(a,b):
assert len(a) == len(b)
start_state = random.getstate()
random.shuffle(a)
random.setstate(start_state)
random.shuffle(b)
a = [1,2,3,4,5,6,7,8,9]
b = [10,11,12,13,14,15,16,17,18,19]
shuffle(a,b)
print(a) # [9, 7, 3, 1, 2, 5, 4, 8, 6]
print(b) # [19, 17, 13, 11, 12, 15, 14, 18, 16]
No estoy seguro de si me estoy perdiendo algo aquí, pero parece que simplemente estás barajando una de las listas y la otra está reorganizada para que coincida con el orden de la primera lista. Entonces, lo que tienes es la mejor manera de hacerlo sin que sea más complicado. Si quieres ir por la ruta complicada, puedes simplemente barajar 1 lista y usar la lista sin barajar para hacer una búsqueda en la lista barajada y reorganizarla de esa manera. Al final terminas con el mismo resultado con el que empezaste. ¿Por qué es un problema crear una tercera lista? Si realmente desea reciclar las listas, simplemente puede reemplazar la lista b con lo que está usando para la lista c y luego separarla de nuevo en a y b.
Si está dispuesto a instalar algunos paquetes más:
Req: NumPy (> = 1.6.1), SciPy (> = 0.9).
pip instalar -U scikit-learn
from sklearn.utils import shuffle
list_1, list_2 = shuffle(list_1, list_2)
Si tiene que hacer esto a menudo, podría considerar agregar un nivel de direccionamiento indirecto mezclando una lista de índices.
Python 2.6.6 (r266:84297, Aug 24 2010, 18:13:38) [MSC v.1500 64 bit (AMD64)] on
win32
Type "help", "copyright", "credits" or "license" for more information.
>>> import random
>>> a = [[1, 2], [3, 4], [5, 6], [7, 8], [9, 10]]
>>> b = [2, 4, 6, 8, 10]
>>> indexes = range(len(a))
>>> indexes
[0, 1, 2, 3, 4]
>>> random.shuffle(indexes)
>>> indexes
[4, 1, 2, 0, 3]
>>> for index in indexes:
... print a[index], b[index]
...
[9, 10] 10
[3, 4] 4
[5, 6] 6
[1, 2] 2
[7, 8] 8
Una respuesta rápida utilizando numpy, por favor consulte here :
Puedes usar
p = numpy.random.permutation(len(a))
Para crear una nueva lista de índices para ambas listas y utilizarla para reordenarlos.
En su escenario:
In [61]: a = [[1, 2], [3, 4], [5, 6], [7, 8], [9, 10]]
In [62]: b = [2, 4, 6, 8, 10]
In [63]: import numpy as np
In [64]: a_ar, b_ar = np.array(a), np.array(b)
In [65]: p = np.random.permutation(len(a))
In [66]: a, b = a_ar[p].tolist(), b_ar[p].tolist()
In [68]: a
Out[68]: [[3, 4], [7, 8], [5, 6], [1, 2], [9, 10]]
In [69]: b
Out[69]: [4, 8, 6, 2, 10]