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