Shuffle an Array with Python, Randomize Array Item Order with Python

Shuffle an array with python, randomize array item order with python

import random
random.shuffle(array)

Shuffle array by group in python

You can do it this way:

import numpy as np
np.random.seed(133)

values = np.array([1,2,3,4,5,6,7,8,9])
groups = np.array([0,0,0,1,1,2,2,3,4])

for index in np.unique(groups):
mask = groups==index
values[mask] = np.random.permutation(values[mask])

print(values)

Output:

[3 1 2 5 4 6 7 8 9]

Shuffling a list of objects

random.shuffle should work. Here's an example, where the objects are lists:

from random import shuffle

x = [[i] for i in range(10)]
shuffle(x)
print(x)

# print(x) gives [[9], [2], [7], [0], [4], [5], [3], [1], [8], [6]]

Note that shuffle works in place, and returns None.

More generally in Python, mutable objects can be passed into functions, and when a function mutates those objects, the standard is to return None (rather than, say, the mutated object).

python: why does random.shuffle change the array

Shuffle from the random module isn’t made to deal with numpy arrays since it’s not exactly the same as nested python lists. You should use the numpy.random module’s shuffle instead.

import numpy as np
from numpy.random import shuffle

arr = np.array([[1,2,3],[4,5,6],[7,8,9]])
shuffle(arr)
print(arr)
# output:
# [[4 5 6]
# [1 2 3]
# [7 8 9]]

Python: Shuffle and put back into initial order elements of an numpy array

The solution is actually to reorder the positions of the transformed array according to the ones of the original output, and not by keeping track of the shuffled indices.

The solution is:

output = np.random.uniform(-1, 1, (4, 1)).ravel()

sorted_weigths = np.sort(abs(output))[::-1]
sorted_indices = np.argsort(abs(output))[::-1]
signs = [i < 0 for i in output]

if np.sum(abs(sorted_weigths)) > 1:
alloc = 1
for i in range(output.shape[0]):
if alloc > abs(sorted_weigths[i]):
sorted_weigths[i] = sorted_weigths[i]
alloc = alloc - abs(sorted_weigths[i])
elif alloc > 0:
sorted_weigths[i] = alloc
alloc = alloc - alloc
else:
sorted_weigths[i] = 0
else:
pass

sorted_weigths_ = copy.deepcopy(sorted_weigths)
for i in range(sorted_indices.shape[0]):
sorted_weigths_[sorted_indices[i]] = sorted_weigths[i]

for i in range(len(signs)):
if signs[i] == True:
sorted_weigths_[i] = -sorted_weigths_[i]
else:
pass

print(output)
print(sorted_weigths_)

How to shuffle the order in a list?

It's because random.shuffle shuffles in place and doesn't return anything (thus why you get None).

import random

words = ['red', 'adventure', 'cat', 'cat']
random.shuffle(words)

print(words) # Possible Output: ['cat', 'cat', 'red', 'adventure']

Edit:

Given your edit, what you need to change is:

from random import shuffle

words = ['red', 'adventure', 'cat', 'cat']
newwords = words[:] # Copy words
shuffle(newwords) # Shuffle newwords

print(newwords) # Possible Output: ['cat', 'cat', 'red', 'adventure']

or

from random import sample

words = ['red', 'adventure', 'cat', 'cat']
newwords = sample(words, len(words)) # Copy and shuffle

print(newwords) # Possible Output: ['cat', 'cat', 'red', 'adventure']

Random shuffle of array, but keep diagonal fixed

One way would be to use masking -

m = ~np.eye(len(A), dtype=bool) # mask of non-diagonal elements

# Extract non-diagonal elements as a new array and shuffle in-place
Am = A[m]
np.random.shuffle(Am)

# Assign back the shuffled values into non-diag positions of input
A[m] = Am

Another way would be to generate the flattened indices and then shuffle and assign -

idx = np.flatnonzero(m)
A.flat[idx] = A.flat[np.random.permutation(idx)]


Related Topics



Leave a reply



Submit