如何从蒙面numpy数组中随机采样元素对,直到元素耗尽而没有任何重复?



我有一个整数/索引数组(即arr_F_idx = np. range(0,200)),我想画100对没有重复。我用一个蒙面数组(我变换arr_F_idx第一次画后,如以下代码所示),但似乎numpy.random.choice仍然吸引了蒙面元素。

arr_F_idx = np.arange(0,200)
draw = np.random.choice(arr_F_idx,2,replace=False)
arr2_Drawn_pairs[0,0] = draw[0]
arr2_Drawn_pairs[0,1] = draw[1]
arr_F_idx_dum1 = np.array(arr_F_idx == draw[0])
arr_F_idx = np.ma.array(arr_F_idx, mask = arr_F_idx_dum1)
arr_F_idx_dum2 = np.array(arr_F_idx == draw[1])
arr_F_idx = np.ma.array(arr_F_idx, mask = arr_F_idx_dum2)
for i in range(1,100):
draw = np.random.choice(arr_F_idx,2,replace=False)
arr2_Drawn_pairs[i,0] = draw[0]
arr2_Drawn_pairs[i,1] = draw[1]
arr_F_idx_dum1 = np.array(arr_F_idx == draw[0])
arr_F_idx = np.ma.array(arr_F_idx, mask = arr_F_idx_dum1)
arr_F_idx_dum2 = np.array(arr_F_idx == draw[1])
arr_F_idx = np.ma.array(arr_F_idx, mask = arr_F_idx_dum2)
我得到的(样本)输出是
arr_F_idx
masked_array(data=[--, --, --, --, 4, 5, --, --, --, --, --, 11, 12, 13,
--, --, 16, 17, --, 19, --, 21, 22, --, 24, --, --, --,
28, --, --, --, 32, 33, 34, --, --, 37, 38, 39, --, 41,
--, --, --, --, --, --, 48, --, --, --, --, --, --, --,
--, 57, 58, --, 60, --, --, 63, 64, --, --, --, --, --,
--, --, --, 73, --, --, 76, --, 78, --, --, --, --, --,
--, --, --, --, 88, 89, --, --, 92, --, --, --, --, --,
98, 99, --, 101, 102, --, --, --, 106, --, --, --, --,
111, --, --, --, --, 116, --, --, --, --, 121, --, 123,
124, 125, --, 127, --, --, --, 131, --, --, --, 135,
--, --, --, --, --, 141, --, --, --, --, --, --, --,
--, --, 151, --, --, --, 155, --, --, --, 159, --, 161,
--, --, --, 165, --, 167, --, 169, --, 171, --, --, --,
--, 176, --, 178, 179, --, --, --, 183, --, 185, --,
--, --, 189, 190, --, --, 193, 194, --, 196, --, 198,
199],
mask=[ True,  True,  True,  True, False, False,  True,  True,
True,  True,  True, False, False, False,  True,  True,
False, False,  True, False,  True, False, False,  True,
False,  True,  True,  True, False,  True,  True,  True,
False, False, False,  True,  True, False, False, False,
True, False,  True,  True,  True,  True,  True,  True,
False,  True,  True,  True,  True,  True,  True,  True,
True, False, False,  True, False,  True,  True, False,
False,  True,  True,  True,  True,  True,  True,  True,
True, False,  True,  True, False,  True, False,  True,
True,  True,  True,  True,  True,  True,  True,  True,
False, False,  True,  True, False,  True,  True,  True,
True,  True, False, False,  True, False, False,  True,
True,  True, False,  True,  True,  True,  True, False,
True,  True,  True,  True, False,  True,  True,  True,
True, False,  True, False, False, False,  True, False,
True,  True,  True, False,  True,  True,  True, False,
True,  True,  True,  True,  True, False,  True,  True,
True,  True,  True,  True,  True,  True,  True, False,
True,  True,  True, False,  True,  True,  True, False,
True, False,  True,  True,  True, False,  True, False,
True, False,  True, False,  True,  True,  True,  True,
False,  True, False, False,  True,  True,  True, False,
True, False,  True,  True,  True, False, False,  True,
True, False, False,  True, False,  True, False, False],
fill_value=999999)

小范围发生;当然对于很小的范围,这不是一个问题,但是正如我提到的,我想排气原始数组,其所有元素将蒙面。问题似乎是np.random.choice仍然以某种方式绘制遮罩元素,即使它不应该(否则我看不到被称为遮罩数组的对象的点)。我可能做错了什么。在这个问题上,如果有一种更简单的方法来绘制成对而不重复,我将不胜感激。

编辑:其实numpy是随机的。Choice绘制遮罩元素,从输出中可以看出(例如,数字177绘制了两次,191绘制了三次):

arr2_Drawn_pairs
Out[53]: 
array([[ 20.,  49.],
[ 35., 114.],
[ 44.,  42.],
[ 52., 140.],
[191.,  59.],    191 - the first time
[147., 144.],
[ 74., 143.],
[ 23.,  43.],
[130.,   1.],
[146., 166.],
[ 62.,  80.],
[ 26., 138.],
[152.,  71.],
[ 50.,  87.],
[ 69.,   9.],
[ 20.,  65.],
[  3., 162.],
[ 30., 104.],
[168., 145.],
[154.,  54.],
[129.,   2.],
[ 79., 170.],
[ 14., 188.],
[107.,  30.],
[119., 188.],
[139.,  94.],
[132., 158.],
[  0.,  69.],
[ 47.,  27.],
[192.,  72.],
[181., 160.],
[ 95., 162.],
[ 40.,  25.],
[107.,   8.],
[128.,  10.],
[  7.,  83.],
[ 91., 173.],
[174.,  10.],
[134.,  82.],
[ 67.,  52.],
[195., 172.],
[197.,  96.],
[ 15., 188.],
[184., 164.],
[ 18., 180.],
[ 45.,  27.],
[ 86.,  84.],
[ 97., 128.],
[149.,   6.],
[109.,  85.],
[182.,  62.],
[ 53.,  68.],
[157.,  81.],
[188.,  25.],
[107.,  45.],
[117.,  86.],
[195.,  47.],
[105., 103.],
[ 51., 162.],
[187., 162.],
[ 70.,  97.],
[ 29., 156.],
[175., 177.],
[  0.,  10.],
[ 87.,  46.],
[  1., 119.],
[ 93.,  90.],
[174.,  53.],
[ 77.,  84.],
[ 84.,  66.],
[ 91., 186.],
[ 83.,  59.],
[137., 140.],
[136., 186.],
[100., 195.],
[173.,  81.],
[120., 115.],
[ 36.,  46.],
[112., 148.],
[118., 103.],
[  8., 128.],
[ 56.,  65.],
[158., 145.],
[180., 122.],
[142., 126.],
[133.,  45.],
[ 59., 173.],
[110., 119.],
[177.,  31.],   177 - the first time!
[ 82., 158.],
[ 53., 113.],
[ 85., 150.],
[126.,  94.],
[ 61., 152.],
[ 93.,  40.],
[  1.,  55.],
[ 96., 162.],
[153., 108.],
[163.,   9.],
[ 75.,  50.],
[101.,  47.],
[178., 148.],
[188., 183.],
[ 69., 177.],    177 - the second time!
[141.,  16.],
[ 31.,  28.],
[106., 147.],
[ 66., 176.],
[156.,  96.],
[  9.,  21.],
[139.,  57.],
[106.,  11.],
[ 25.,   2.],
[152.,  69.],
[ 34., 169.],
[148., 191.],    191 - the second time!
[105.,  32.],
[187., 156.],
[105., 191.],    191 - the third time!
[ 53., 128.],
[ 56.,  30.],
[176.,   7.],
[168., 150.],
[ 48., 101.],
[105., 167.]])

编辑2:获得我想要的结果的一个蛮力方法可能是创建一个新的数组从每次抽取后采样,

arr_F_idx_iter = np.append(arr_F_idx[0:draw[0]],arr_F_idx[draw[0]+1:199])

,但我认为这是否可以有效地完成与掩码数组的问题仍然是合法的,因为它会更快,也许还指出了一个缺陷在掩码数组如何工作。

一个简单的1d掩码数组:

In [28]: m = np.ma.masked_array(np.arange(10), mask=np.random.randint(0,2,10))    
In [29]: m
Out[29]: 
masked_array(data=[--, --, 2, 3, --, --, 6, 7, --, --],
mask=[ True,  True, False, False,  True,  True, False, False,
True,  True],
fill_value=999999)

choice,没有特殊的ma知识,从data属性中提取:

In [31]: np.random.choice(m,3, replace=False)
Out[31]: array([4, 3, 8])
In [32]: np.random.choice(m.data,3, replace=False)
Out[32]: array([1, 8, 5])

如果您希望它从未屏蔽的元素中绘制,您需要给它这样一个数组,compressed:

In [33]: np.random.choice(m.compressed(),3, replace=False)
Out[33]: array([2, 6, 3])

一般np函数不能正确地在掩码数组上工作。这就是为什么有大量的np.ma函数(和ma方法)。这些函数通常使用compressed来获取未掩码的值。或者他们用一些"无辜的"来代替被掩盖的值;填充。

In [35]: m.data
Out[35]: array([0, 1, 2, 3, 4, 5, 6, 7, 8, 9])
In [36]: m.compressed()
Out[36]: array([2, 3, 6, 7])
In [37]: m.filled()
Out[37]: 
array([999999, 999999,      2,      3, 999999, 999999,      6,      7,
999999, 999999])
In [38]: m.filled(0)
Out[38]: array([0, 0, 2, 3, 0, 0, 6, 7, 0, 0])

相关内容

  • 没有找到相关文章

最新更新