Ich habe zwei numpy Arrays unterschiedlicher Form, aber mit der gleichen Länge (führende Dimension). Ich möchte jeden von ihnen so mischen, dass die entsprechenden Elemente weiterhin übereinstimmen - dh sie in Bezug auf ihre Leitindizes im Einklang mischen.
Dieser Code funktioniert und veranschaulicht meine Ziele:
def shuffle_in_unison(a, b):
assert len(a) == len(b)
shuffled_a = numpy.empty(a.shape, dtype=a.dtype)
shuffled_b = numpy.empty(b.shape, dtype=b.dtype)
permutation = numpy.random.permutation(len(a))
for old_index, new_index in enumerate(permutation):
shuffled_a[new_index] = a[old_index]
shuffled_b[new_index] = b[old_index]
return shuffled_a, shuffled_b
Beispielsweise:
>>> a = numpy.asarray([[1, 1], [2, 2], [3, 3]])
>>> b = numpy.asarray([1, 2, 3])
>>> shuffle_in_unison(a, b)
(array([[2, 2],
[1, 1],
[3, 3]]), array([2, 1, 3]))
Dies fühlt sich jedoch klobig, ineffizient und langsam an und erfordert das Erstellen einer Kopie der Arrays. Ich würde sie lieber an Ort und Stelle mischen, da sie ziemlich groß sind.
Gibt es einen besseren Weg, dies zu tun? Schnellere Ausführung und geringere Speichernutzung sind meine Hauptziele, aber eleganter Code wäre auch schön.
Ein anderer Gedanke, den ich hatte, war folgender:
def shuffle_in_unison_scary(a, b):
rng_state = numpy.random.get_state()
numpy.random.shuffle(a)
numpy.random.set_state(rng_state)
numpy.random.shuffle(b)
Das funktioniert ... aber es ist ein wenig beängstigend, da ich wenig Garantie dafür sehe, dass es weiterhin funktioniert - es sieht nicht so aus, als würde es zum Beispiel in der Numpy-Version garantiert überleben.