Tôi có hai mảng numpy có hình dạng khác nhau, nhưng có cùng chiều dài (kích thước hàng đầu). Tôi muốn xáo trộn từng người trong số họ, sao cho các yếu tố tương ứng tiếp tục tương ứng - tức là trộn chúng lại với nhau theo các chỉ số hàng đầu của họ.
Mã này hoạt động và minh họa các mục tiêu của tôi:
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
Ví dụ:
>>> 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]))
Tuy nhiên, điều này cảm thấy cồng kềnh, không hiệu quả và chậm chạp, và nó đòi hỏi phải tạo một bản sao của các mảng - tôi muốn thay đổi chúng tại chỗ, vì chúng sẽ khá lớn.
Có cách nào tốt hơn để đi về điều này? Thực thi nhanh hơn và sử dụng bộ nhớ thấp hơn là mục tiêu chính của tôi, nhưng mã thanh lịch cũng sẽ rất tốt.
Một ý nghĩ khác mà tôi có là:
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)
Điều này hoạt động ... nhưng nó hơi đáng sợ, vì tôi thấy một chút đảm bảo rằng nó sẽ tiếp tục hoạt động - chẳng hạn như nó không phải là thứ được đảm bảo để tồn tại qua phiên bản numpy, chẳng hạn.