如何为 numpy 数组中的每个类别随机选择 1 个样本(整数编码)



我使用整数编码来表示numpy数组中的类别。但是,我不知道如何为每个类别随机抽取 1 个样本并返回索引值。

例如,我有一个数组,如下所示:

np.array([2, 2, 2, 2, 2, 2, 2, 1, 2, 2, 1, 1, 1, 0, 1, 0, 0, 2, 2, 1])

如何随机抽取 0、1 和 2 并返回每个样本的索引?

矢量化整数标签的通用数量 -

# https://stackoverflow.com/a/51915131/ @Divakar
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
# a is input array
sidx = a.argsort()
c = np.bincount(a)
out = sidx[random_num_per_grp(c) + np.r_[0,c[:-1].cumsum()]]

为了简化我们的情况,我们可以跳过random_num_per_grp最后部分的偏移量。因此,它将是 - return r1.argsort()[offset]然后得到out,它将是 - sidx[random_num_per_grp(c)] .

对于负标签,只需偏移最小值即可。

您可以使用

np.wherenp.random.choice()

x = np.array([2, 2, 2, 2, 2, 2, 2, 1, 2, 2, 1, 1, 1, 0, 1, 0, 0, 2, 2, 1])
ind0 = np.random.choice(np.where(x==0)[0])
ind1 = np.random.choice(np.where(x==1)[0])
ind2 = np.random.choice(np.where(x==2)[0])

由于np.where返回一个元组,其中包含一个数组,因此要访问该数组,您需要访问元组的 0 索引。

import numpy as np
array = np.array([2, 2, 2, 2, 2, 2, 2, 1, 2, 2, 1, 1, 1, 0, 1, 0, 0, 2, 2, 1])
categories = [0,1,2]
for category in categories:
    indices = np.where(array  == category)[0]
    random_choice = array[np.random.choice(indices)]

1(获取数字索引,其中您的条件为真(类别(2(从这些索引中随机选择

如果您

事先不知道类别,则可以执行以下操作:

import numpy as np
from numpy.random import choice
a = np.array([2, 2, 2, 2, 2, 2, 2, 1, 2, 2, 1, 1, 1, 0, 1, 0, 0, 2, 2, 1])
samples = [choice(np.argwhere(a==s).flatten()) for s in np.unique(a)]

首先,您需要知道类别是什么。 set(iterable)是一种方便的方法。

然后,np.where可以告诉数组中某个对象的所有索引。

最后,从每个类别的索引中随机选择一个。

import random
import numpy as np
def random_index_each(array):
    def random_index(item):
        return (item, random.choice(np.where(array == item)[0]))
    return dict(map(random_index, set(array)))
if __name__ == '__main__':
    array = np.array([2, 2, 2, 2, 2, 2, 2, 1, 2, 2, 1, 1, 1, 0, 1, 0, 0, 2, 2, 1])
    for _ in range(4):
        print(random_index_each(array))

输出:

{0: 16, 1: 12, 2: 8}
{0: 15, 1: 14, 2: 6}
{0: 15, 1: 19, 2: 6}
{0: 15, 1: 11, 2: 2}

如果您不关心从哪个类别中选取索引,则可以使用list来还原结果。或者让它以可迭代对象的形式存在。

最新更新