簡體   English   中英

如何隨機獲取 numpy 數組的一定數量的元素,每個 class 至少有一個元素?

[英]How do I randomly get a certain number of elements of a numpy array with at least one element from each class?

我有一個包含 400 張圖像的數據集,其中 10 張圖像來自 40 個不同的人。 有 2 個 NumPy arrays,“olivetti_faces”包含圖像(400x64x64),“olivetti_faces_target”包含這些圖像的類別(400),每個人一個 class。 所以“olivetti_faces”的形式是: array([<img1>, <img2>, ..., <img400>])其中<img>是一個 64x64 的數字數組,“olivetti_faces_target”的形式是: array([0, 0, ..., 39])

您可以在此處訪問數據集。 您可以在下載后加載它們,如下所示:

import numpy as np
data=np.load("olivetti_faces.npy")
target=np.load("olivetti_faces_target.npy")

我想隨機選擇 100 張圖片,這 40 個人至少每人一張圖片。 我怎樣才能在 NumPy 中實現這一點?

到目前為止,我可以使用以下代碼隨機獲取 100 張圖像:

n = 100 # number of images to retrieve
rand_indeces = np.random.choice(data.shape[0], n, replace=False)
data_random = data[rand_indeces]
target_random = target_random[rand_indeces]

但它不保證data_random中至少包含 40 個類別中每個類別的一張圖像。

正如我的評論中所建議的,首先從每個 class 中選擇一個隨機索引。然后從整個數組中選擇隨機索引。 這將保證每個 class 在最終結果中都有一個條目。

由於每個 class 都有 10 個元素,您可以遍歷 0-39 類並選擇一個 0-9 的值。

試試這個代碼:

import numpy as np
import random

data=np.load("olivetti_faces.npy")
target=np.load("olivetti_faces_target.npy")

# target is groups of 10, so select random index in each block
for i in range(40):  # class 0-39
   rndindex.append(i*10 + random.randint(0,9)) # one per class
   
for i in range(60):  # up to 100
   idx = rndindex[0]
   while idx in rndindex:  # prevent duplicates
       idx = random.randint(0,399)  # other indexes can be anywhere
   rndindex.append(idx)

rand_indeces = []  # np array objects
for idx in rndindex:
   rand_indeces.append(data[idx])

print(rndindex)
#print(rand_indeces)

Output(注意前 40 個以 10 個為一組)

[9, 17, 23, 31, 41, 52, 60, 72, 83, 95, 
 100, 119, 121, 136, 140, 150, 166, 175, 188, 198, 
 209, 211, 221, 238, 243, 250, 261, 276, 289, 290, 
 306, 315, 325, 333, 344, 351, 368, 376, 382, 391, 
 62, 296, 327, 241, 393, 215, 64, 59, 185, 286, 
 162, 163, 364, 309, 220, 273, 32, 214, 217, 182, 
 172, 98, 19, 358, 92, 322, 68, 399, 226, 285, 
 103, 155, 249, 1, 75, 303, 311, 125, 339, 106, 
 127, 94, 101, 113, 35, 20, 189, 199, 128, 30, 
 131, 317, 337, 156, 340, 99, 397, 385, 384, 193]

正如@xrisk 所建議的那樣,一種方法是隨機獲取 100 張圖像,直到滿足條件為止,如下所示:

n = 100 # number of images to retrieve
n_unique = len(np.unique(target)) # number of classes
containsAllCats = False
while not containsAllCats:
    rand_indeces = np.random.choice(data.shape[0], n, replace=False)
    data_random = data[rand_indeces]
    target_random = target[rand_indeces]
    containsAllCats = len(np.unique(target_random)) == n_unique

然而,它似乎相當低效,大部分時間需要多次迭代。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM