Проблема с добавлением в список внутри цикла с помощью np.random.shuffle () - PullRequest
0 голосов
/ 02 октября 2018

Я застрял в следующем коде, где я хочу перетасовать список нужное количество раз, а затем сохранить результат в месте, находясь внутри цикла.Я вижу, что в цикле перетасовка выполняется правильно, но я не могу получить тот же результат, хранящийся в списке.

import pandas as pd
import numpy as np
from scipy import stats
class shuffle():
     def __init__(self,arr,i):
         new=[]                                                                                                                                                 
         for ii in range(i):                 
             np.random.shuffle(arr)
             print arr
             new.append(arr)             
         self.new2 = np.asarray(new)
     def f():
         #print self.new2
         return self.new2

a = np.linspace(1,4,10)
s=shuffle(a,3)     

вход 'a' равен

[1.        , 1.33333333, 1.66666667, 2.        , 2.33333333,
       2.66666667, 3.        , 3.33333333, 3.66666667, 4.        ])  

вывод на печать внутри класса (перемешан 3 раза) дает:

print arr

[2.         1.66666667 4.         1.         3.33333333 2.33333333
 3.66666667 1.33333333 3.         2.66666667]
[2.33333333 2.         1.33333333 1.66666667 3.66666667 1.
 3.33333333 3.         2.66666667 4.        ]
[2.         3.66666667 2.33333333 4.         1.66666667 1.33333333
 3.         3.33333333 2.66666667 1.        ]

Но вывод массива 'new2 'дает следующий результат вместо ожидаемого выше результата:

s.new2
Out[15]: 
array([[2.        , 3.66666667, 4.        , 3.33333333, 2.33333333,
        2.66666667, 1.        , 1.33333333, 3.        , 1.66666667],
       [2.        , 3.66666667, 4.        , 3.33333333, 2.33333333,
        2.66666667, 1.        , 1.33333333, 3.        , 1.66666667],
       [2.        , 3.66666667, 4.        , 3.33333333, 2.33333333,
        2.66666667, 1.        , 1.33333333, 3.        , 1.66666667]])

Ответы [ 2 ]

0 голосов
/ 02 октября 2018

Это решение, благодаря ответу @a_guest

class shuffle():
    ...:      def __init__(self,arr,i):
    ...:          new=[]                                                                                                                                         
    ...:         
    ...:          for ii in range(i):                 
    ...:              arr2=arr.copy()
    ...:              np.random.shuffle(arr2)
    ...:              print arr2
    ...:              new.append(arr2)             
    ...:          self.new2 = np.asarray(new)
    ...:      def f():
    ...:          #print self.new2
    ...:          return self.new2

Вывод теперь соответствует ожиданиям:

s.new2
Out[34]: 
array([[3.        , 1.        , 3.66666667, 2.66666667, 1.66666667,
        2.33333333, 1.33333333, 4.        , 2.        , 3.33333333],
       [4.        , 3.66666667, 3.        , 2.33333333, 1.66666667,
        1.33333333, 2.66666667, 1.        , 3.33333333, 2.        ],
       [2.        , 3.        , 2.33333333, 4.        , 3.33333333,
        1.        , 1.66666667, 1.33333333, 2.66666667, 3.66666667]])
0 голосов
/ 02 октября 2018

Как вы упомянули np.random.shuffle изменит массив на месте.Поскольку вы добавляете сам массив (фактически ссылку на него) в список new, в конце он содержит три ссылки на один и тот же массив (содержащий значения из последней перестановки).Попробуйте напечатать [id(x) for x in s.new2], чтобы убедить себя.Вместо этого вы можете добавить копию через new.append(arr.copy()).

...