numpy数组:具有随机关系的行列明智argmax

numpy数组:具有随机关系的行列明智argmax,第1张

numpy数组:具有随机关系的行/列明智argmax 通用案例解决方案,每组一个

要解决从指定列表范围的数字列表/数字数组中选择随机数的一般情况,我们将使用一个技巧来创建一个统一的rand数组,添加由间隔长度指定的偏移量,然后执行

argsort
。实现看起来像这样-

def random_num_per_grp(L):    # For each element in L pick a random number within range specified by it    r1 = np.random.rand(np.sum(L)) + np.repeat(np.arange(len(L)),L)    offset = np.r_[0,np.cumsum(L[:-1])]    return r1.argsort()[offset] - offset

样品盒-

In [217]: L = [5,4,2]In [218]: random_num_per_grp(L) # i.e. select one per [0-5,0-4,0-2]Out[218]: array([2, 0, 1])

因此,输出将具有与输入中相同数量的元素

L
而第一个输出元素将位于in中
[0,5)
,第二个元素
[0,4)
等等。


在这里解决我们的问题

为了解决这里的问题,我们将使用修改后的版本(特别是在函数的末尾删除偏移量删除部分,就像这样-

def random_num_per_grp_cumsumed(L):    # For each element in L pick a random number within range specified by it    # The final output would be a cumsumed one for use with indexing, etc.    r1 = np.random.rand(np.sum(L)) + np.repeat(np.arange(len(L)),L)    offset = np.r_[0,np.cumsum(L[:-1])]    return r1.argsort()[offset]

方法1

一种解决方案可以像这样使用它-

def argmax_per_row_randtie(a):    max_mask = a==a.max(1,keepdims=1)    m,n = a.shape    all_argmax_idx = np.flatnonzero(max_mask)    offset = np.arange(m)*n    return all_argmax_idx[random_num_per_grp_cumsumed(max_mask.sum(1))] - offset

验证

让我们用大量的运行来测试给定的样本,并计算每一行每个索引的出现次数

In [235]: aOut[235]: array([[1, 3, 3],       [4, 5, 6],       [7, 8, 1]])In [225]: all_out = np.array([argmax_per_row_randtie(a) for i in range(10000)])# The first element (row=0) should have similar probabilities for 1 and 2In [236]: (all_out[:,0]==1).mean()Out[236]: 0.504In [237]: (all_out[:,0]==2).mean()Out[237]: 0.496# The second element (row=1) should only have 2In [238]: (all_out[:,1]==2).mean()Out[238]: 1.0# The third element (row=2) should only have 1In [239]: (all_out[:,2]==1).mean()Out[239]: 1.0

方法2:

masking
用于表现

我们可以利用

masking
并因此避免
flatnonzero
像通常使用布尔数组那样获得性能的意图。此外,我们将概括性地覆盖行(轴= 1)和列(轴=
0),以便为我们自己修改,例如-

def argmax_randtie_masking_generic(a, axis=1):     max_mask = a==a.max(axis=axis,keepdims=True)    m,n = a.shape    L = max_mask.sum(axis=axis)    set_mask = np.zeros(L.sum(), dtype=bool)    select_idx = random_num_per_grp_cumsumed(L)    set_mask[select_idx] = True    if axis==0:        max_mask.T[max_mask.T] = set_mask    else:        max_mask[max_mask] = set_mask    return max_mask.argmax(axis=axis)

在样品运行

axis=0
axis=1
-

In [423]: aOut[423]: array([[1, 3, 3],       [4, 5, 6],       [7, 8, 1]])In [424]: argmax_randtie_masking_generic(a, axis=1)Out[424]: array([1, 2, 1])In [425]: argmax_randtie_masking_generic(a, axis=1)Out[425]: array([2, 2, 1])In [426]: a[1,1] = 8In [427]: aOut[427]: array([[1, 3, 3],       [4, 8, 6],       [7, 8, 1]])In [428]: argmax_randtie_masking_generic(a, axis=0)Out[428]: array([2, 1, 1])In [429]: argmax_randtie_masking_generic(a, axis=0)Out[429]: array([2, 1, 1])In [430]: argmax_randtie_masking_generic(a, axis=0)Out[430]: array([2, 2, 1])


欢迎分享,转载请注明来源:内存溢出

原文地址: https://outofmemory.cn/zaji/5674585.html

(0)
打赏 微信扫一扫 微信扫一扫 支付宝扫一扫 支付宝扫一扫
上一篇 2022-12-17
下一篇 2022-12-16

发表评论

登录后才能评论

评论列表(0条)

保存