Saya memiliki dua array numpy dengan bentuk yang berbeda, tetapi dengan panjang yang sama (dimensi terdepan). Saya ingin mengocok masing-masing, sehingga elemen yang sesuai terus berkorespondensi - yaitu mengocoknya bersamaan sehubungan dengan indeks utama mereka.
Kode ini berfungsi, dan menggambarkan tujuan saya:
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
Sebagai contoh:
>>> 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]))
Namun, ini terasa kikuk, tidak efisien, dan lambat, dan perlu membuat salinan array - saya lebih suka mengocoknya di tempat, karena mereka akan cukup besar.
Apakah ada cara yang lebih baik untuk melakukan ini? Eksekusi lebih cepat dan penggunaan memori yang lebih rendah adalah tujuan utama saya, tetapi kode yang elegan juga bagus.
Satu pemikiran lain yang saya miliki adalah ini:
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)
Ini berfungsi ... tapi ini sedikit menakutkan, karena saya melihat sedikit jaminan itu akan terus bekerja - itu tidak terlihat seperti hal yang dijamin untuk bertahan hidup di seluruh versi numpy, misalnya.