0

I want to shuffle/permute the rows of a list of lists (2D array) target in Python.

I create the list train and then shuffle it by np.random.shuffle(), and use it to permute indices of rows of target in the same order.

I know I can't just write new_list = old_list to copy one list to other , so (I think) I used a proper way to copy target to cop by cop = [row[:] for row in target] mentioned here on SO.

But even after running the code below I can't figure out why cop changes value during the loop. As a result, target isn't what I expect.

Code I am attempting:

import numpy as np

train = [0, 1, 2, 3, 4]

print("train: ", train)
target = np.hstack([np.arange(5).reshape(5,1), np.arange(100, 105).reshape(5,1), 
np.arange(200, 205).reshape(5,1)])

print(target)

np.random.shuffle(train)
print("Shuffled train: ", train)
cop = [row[:] for row in target]

for i in range(len(train)):
    print(train[i], '-----', cop[train[i]], '-------', cop)
    target[i] = list(cop[train[i]])

print("Target: ", target)

print("Cop: ", cop)

Sample output:

train: [0, 1, 2, 3, 4]
[[  0 100 200]
 [  1 101 201]
 [  2 102 202]
 [  3 103 203]
 [  4 104 204]]
Shuffled train: [4, 3, 2, 0, 1]
4 ----- [  4 104 204] ------- [array([  0, 100, 200]), array([  1, 101, 
201]), array([  2, 102, 202]), array([  3, 103, 203]), array([  4, 104, 
204])]
3 ----- [  3 103 203] ------- [array([  4, 104, 204]), array([  1, 101, 
201]), array([  2, 102, 202]), array([  3, 103, 203]), array([  4, 104, 
204])]
2 ----- [  2 102 202] ------- [array([  4, 104, 204]), array([  3, 103, 
203]), array([  2, 102, 202]), array([  3, 103, 203]), array([  4, 104, 
204])]
0 ----- [  4 104 204] ------- [array([  4, 104, 204]), array([  3, 103, 
203]), array([  2, 102, 202]), array([  3, 103, 203]), array([  4, 104, 
204])]
1 ----- [  3 103 203] ------- [array([  4, 104, 204]), array([  3, 103, 
203]), array([  2, 102, 202]), array([  4, 104, 204]), array([  4, 104, 
204])]
Target:  [[  4 104 204]
 [  3 103 203]
 [  2 102 202]
 [  4 104 204]
 [  3 103 203]]
Cop:  [array([  4, 104, 204]), array([  3, 103, 203]), array([  2, 102, 202]), array([  4, 104, 204]), array([  3, 103, 203])]

Process finished with exit code 0

ab123
  • 203
  • 4
  • 12
  • 1
    instead of copying the values by hand of a type that is held as reference (in python that is everything except the primitive types like bool, int, float, str), I recommend to use `target = copy.copy(source)` – mzoll Jun 07 '18 at 09:23
  • @MarcelZoll That worked, but why did slicing operator on every row not work? – ab123 Jun 07 '18 at 09:25
  • 1
    firstly, to achieve your goal here, i recommend the use of `numpy.take()`; to answer your question why your slicing assignments fails: `cop` still referes to the lists in `target`, which is modified during the loop; as said,complex types should always be explicitly copied – mzoll Jun 07 '18 at 10:05

0 Answers0