Inverse of random.shuffle()? Inverse of random.shuffle()? python-3.x python-3.x

Inverse of random.shuffle()?


Just wanted to contribute an answer that's more compatible with functional patterns commonly used with numpy. Ultimately this solution should perform the fastest as it will take advantage of numpy's internal optimizations, which themselves can be further optimized via the use of projects like numba. It ought to be much faster than using conventional loop structures in python.

import numpy as nporiginal_data = np.array([23, 44, 55, 19, 500, 201]) # Some random numbers to represent the original data to be shuffleddata_length = original_data.shape[0]# Here we create an array of shuffled indicesshuf_order = np.arange(data_length)np.random.shuffle(shuf_order)shuffled_data = original_data[shuf_order] # Shuffle the original data# Create an inverse of the shuffled index array (to reverse the shuffling operation, or to "unshuffle")unshuf_order = np.zeros_like(shuf_order)unshuf_order[shuf_order] = np.arange(data_length)unshuffled_data = shuffled_data[unshuf_order] # Unshuffle the shuffled dataprint(f"original_data: {original_data}")print(f"shuffled_data: {shuffled_data}")print(f"unshuffled_data: {unshuffled_data}")assert np.all(np.equal(unshuffled_data, original_data))


Here are two functions that do what you need:

import randomimport numpy as npdef shuffle_forward(l):    order = range(len(l)); random.shuffle(order)    return list(np.array(l)[order]), orderdef shuffle_backward(l, order):    l_out = [0] * len(l)    for i, j in enumerate(order):        l_out[j] = l[i]    return l_out

Example

l = range(10000); random.shuffle(l)l_shuf, order = shuffle_forward(l)l_unshuffled  = shuffle_backward(l_shuf, order)print l == l_unshuffled#True


Reseed the random generator with the seed in question and then shuffle the list 1, 2, ..., n. This tells you exactly what ended up where in the shuffle.