2

I have these two 1d arrays A = [0, 1, 2, 3, 4, 5, 6, 7, 8, 9] and its label L = [9, 8, 7, 6, 5, 4, 3, 2, 1, 0]; where L[i] is the label of A[i].

Objective : I need to randomly shuffle both the 1d arrays in such a way that their labels stay in the same index.

e.g: After shuffle:
A= [2, 4, 9, 1, 3, 6, 0, 7, 5] then L= [7, 5, 0, 8, 6, 3, 9, 2, 4], A[i] and L[i] should remain same as the original one.

I was thinking of concatenating the above two 1d arrays into a single 2d array and reshuffle it, then again separate the two 1d arrays. It's not working. And I am stuck at reshuffle.

Below is the code that I tried

import numpy as np
import random    
# initializing the contents    
A = np.arange(0,10)
length= len(A)
print length
print A

labels = np.zeros(10)

for index in range(length):
    labels[index] = A[length-index-1]

print labels
# end, contents ready

combine = []
combine.append([A, labels])
print combine
random.shuffle(combine)
print "After shuffle"
print combine
Cœur
  • 37,241
  • 25
  • 195
  • 267
OnePunchMan
  • 720
  • 15
  • 33

3 Answers3

2

If you are using Numpy just use a numpythonic approach. Create the pairs using np.column_stack and shuffle them with numpy.random.shuffle function:

pairs = np.column_stack((A, L))
np.random.shuffle(pairs)

Demo:

In [16]: arr = np.column_stack((A, L))

In [17]: np.random.shuffle(arr)

In [18]: arr
Out[18]: 
array([[4, 5],
       [5, 4],
       [7, 2],
       [1, 8],
       [3, 6],
       [6, 3],
       [8, 1],
       [2, 7],
       [9, 0],
       [0, 9]])

If you want to get the arrays just do a simple indexing:

In [19]: arr[:,0]
Out[19]: array([4, 5, 7, 1, 3, 6, 8, 2, 9, 0])

In [20]: arr[:,1]
Out[20]: array([5, 4, 2, 8, 6, 3, 1, 7, 0, 9])
Mazdak
  • 105,000
  • 18
  • 159
  • 188
1

Your thought was in the right direction. You just needed some Python-Fu:

from random import shuffle

A = [0, 1, 2, 3, 4, 5, 6, 7, 8, 9]
L = [9, 8, 7, 6, 5, 4, 3, 2, 1, 0]

res = list(zip(A, L))
shuffle(res)  # shuffles in-place!

A, L = zip(*res)  # unzip
print(A)  # -> (4, 0, 2, 1, 8, 7, 9, 6, 5, 3)
print(L)  # -> (5, 9, 7, 8, 1, 2, 0, 3, 4, 6)

The unzipping operation is explained here in detail in case you are wondering how it works.

talonmies
  • 70,661
  • 34
  • 192
  • 269
Ma0
  • 15,057
  • 4
  • 35
  • 65
  • Thanks a lot. its working! one thing i didn't get is why print L is showing as [ 9. 8. 7. 6. 5. 4. 3. 2. 1. 0.] instead of [9, 8, 7, 6, 5, 4, 3, 2, 1, 0] – OnePunchMan Feb 22 '18 at 13:52
  • @OnePunchMan I cannot re-create your problem. Where are you running this? Are `L` and `A` `numpy` arrays? – Ma0 Feb 22 '18 at 13:54
  • the above problem is just a small portion of a bigger problem, i am learning it part by part. I haven't yet decided whether to use numpy or not. But as for the above mentioned problem, label as initially initialized as a numpy array. – OnePunchMan Feb 22 '18 at 13:58
  • will it work if A is a 2 D array with same length as L? – OnePunchMan Feb 22 '18 at 14:09
0

You can also keep an index array np.arange(size) where size is the length of A and L and do shuffling on this array. Then use this array to rearrange A and L.

idx = np.arange(10)
np.random.shuffle(idx) # or idx = np.random.shuffle(np.arange(10))

A = np.arange(100).reshape(10, 10)
L = np.array([9, 8, 7, 6, 5, 4, 3, 2, 1, 0])

L[idx], A[idx] 
# output
(array([2, 5, 1, 7, 8, 9, 0, 6, 4, 3]),
 array([[70, 71, 72, 73, 74, 75, 76, 77, 78, 79],
        [40, 41, 42, 43, 44, 45, 46, 47, 48, 49],
        [80, 81, 82, 83, 84, 85, 86, 87, 88, 89],
        [20, 21, 22, 23, 24, 25, 26, 27, 28, 29],
        [10, 11, 12, 13, 14, 15, 16, 17, 18, 19],
        [ 0,  1,  2,  3,  4,  5,  6,  7,  8,  9],
        [90, 91, 92, 93, 94, 95, 96, 97, 98, 99],
        [30, 31, 32, 33, 34, 35, 36, 37, 38, 39],
        [50, 51, 52, 53, 54, 55, 56, 57, 58, 59],
        [60, 61, 62, 63, 64, 65, 66, 67, 68, 69]]))

Reference

Numpy: Rearrange array based upon index array

Tai
  • 7,684
  • 3
  • 29
  • 49