使用 np.random.shuffle() 在循环内附加到列表的问题

Problem appending to a list inside a loop using np.random.shuffle()

我被困在下面的代码中,我想在其中随机播放列表所需的次数,然后在循环内将结果存储在一个地方。我可以看到在循环内正确执行了改组,但我无法将相同的结果存储在列表中。

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.        ])  

class 中的打印输出(洗牌 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]])

如您所述,np.random.shuffle 将就地修改数组。由于您将数组本身(实际上是对它的引用)附加到 new 列表,最后它包含对同一数组的三个引用(包含上次改组的值)。尝试打印 [id(x) for x in s.new2] 来说服自己。相反,您可以通过 new.append(arr.copy()).

附加副本

这就是解决方案,感谢@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]])