一个numpy数组中非零值的随机索引

5
我希望这个问题之前没有被问过。不确定如何重新表达问题。这个帖子非常相似,但仍然不完全是我想要的。
我有一个长度可变的numpy数组(大约在4-12之间)。数组的值为0或1。我想从数组中获取一个随机样本的索引,该索引不为0。
我的想法是这样的:
def sample(self):
        flag = 0
        while flag == 0:
            sampleValue = randint(0, len(myArray())-1)
            flag = myArray()[sampleValue]
        return sampleValue

但这不是好的代码,最终会陷入无限循环中。当然我可以改进它。很有可能在Python中有更优美的方式来做这件事 :)

2个回答

6
您可以使用numpy.nonzero获取数组a中非零元素的索引。
>>> a = np.array([1, 0, 1, 0, 1, 1, 1, 0, 0])
>>> idx_nonzero, = np.nonzero(a)
>>> 
>>> idx_nonzero
array([0, 2, 4, 5, 6])

然后使用numpy.random.choice从这些值中选择一个。

>>> np.random.choice(idx_nonzero)
5

1
哇,Python太棒了。非常感谢! - Mr.Sh4nnon

2
您可以首先使用以下方法生成索引列表,这些索引是1的:

my_idcs = np.where(my_array)[0]

那么你可以使用random.choice随机获取其中一个索引:

from random import choice

my_idx = choice(np.where(my_array)[0])

这将返回一个单一的索引,对应值为my_array[my_idx]1

请注意,如果my_array中没有1,则会引发IndexError异常。


非常感谢!就效率而言,与@timgeb的解决方案相比,哪一个更快,或者执行的代码在后台几乎相同? - Mr.Sh4nnon
1
没错,只有一个参数的 np.where 等同于 np.nonzero。我从来不喜欢 np.where 的这种功能。我宁愿将其删除并将 np.where 重命名为 np.ifthenelse。 :) - timgeb
1
@Mr.Sh4nnon:通常时间上的差异会非常小,因为本质上两者都运行相同的算法。我同意timgeb的观点,np.where 可能有些“随意”的命名方式,但这并不是我发明的 :)。 - Willem Van Onsem
非常感谢您们,但很抱歉我不能给你们两个都加上贡献。 - Mr.Sh4nnon

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接