在满足给定要求的同时从矩阵中抽样

时间:2017-01-27 17:41:52

标签: python algorithm

有一个0-1矩阵,我需要从该矩阵中抽取1个值的M个不同条目。是否有针对此类要求的高效Python工具?

基线方法是在每次迭代期间进行M次迭代,随机采样1,如果值为1,则保留并保存其位置,否则,继续此迭代直到找到值为1的条目;并继续下一次迭代。它似乎不是一个好的启发式方法。

2 个答案:

答案 0 :(得分:0)

我选择间接索引numpy.nonzero

的回报

通过在ndx_ndx列表上使用pop()将一个(间接)索引放入输入数组而无需替换

当你得到所有的

时,ndx_ndx最终会被清空
import numpy as np


ary = np.random.randint(2, size=(20, 20))

# get the indices of all of the ones

ndx_ary_ones = np.nonzero(ary)

# make a range list for pointing into ndx_ary_ones

ndx_ndx = list(range(len(ndx_ary_ones[0])))

# randomize the order

np.random.shuffle(ndx_ndx)

# pop the last ndx_ndx

a_ran_ndx_ndx = ndx_ndx.pop()

# get the index tuple for the one in ary that we removed from ndx_ndx

a_ran_one_ndx = (ndx_ary_ones[0][a_ran_ndx_ndx],
                 ndx_ary_ones[1][a_ran_ndx_ndx])

# testing...

print('ary', ary, '\n')
print('ndx_ary_ones ', *ndx_ary_ones, sep = '\n')
print('\n','ndx_ndx[0:10] ', ndx_ndx[0:10], '\n')

for _ in range (10):
    a_ran_ndx_ndx = ndx_ndx.pop()
    a_ran_one_ndx = (ndx_ary_ones[0][a_ran_ndx_ndx],
                     ndx_ary_ones[1][a_ran_ndx_ndx])
    print(a_ran_one_ndx, ary[a_ran_one_ndx])

ary [[0 0 0 ..., 1 1 1]
 [0 1 1 ..., 1 1 1]
 [1 0 0 ..., 1 0 1]
 ..., 
 [1 1 0 ..., 1 0 1]
 [1 1 0 ..., 1 1 1]
 [1 0 0 ..., 0 0 1]] 

ndx_ary_ones 
[ 0  0  0 ..., 19 19 19]
[ 3  5  7 ..., 14 15 19]

 ndx_ndx[0:10]  [121, 43, 146, 69, 64, 3, 29, 186, 98, 30] 

(7, 12) 1
(8, 18) 1
(0, 3) 1
(10, 2) 1
(18, 18) 1
(17, 7) 1
(15, 14) 1
(4, 11) 1
(10, 1) 1
(4, 4) 1

答案 1 :(得分:0)

我们可以通过以下方式完成:首先得到矩阵A的所有(x,y)元组(索引),其中A [x,y] = 1。让k有这样的指数。现在滚动一个k侧无偏骰子M次(我们可以使用函数randint(1,k)从均匀分布中抽取样本来模拟)。如果您想要具有替换的样本(可以多次选择矩阵的相同位置),则可以使用函数的M调用来完成。否则,对于具有替换的样本(不允许重复),您需要跟踪已经选择的位置,并在下次投掷潜水之前从阵列中删除这些索引。