Tomonaga
Tomonaga

Reputation: 167

Get random element on condition

I have two lists: images and corresponding labels. I want to get a random image by a given label.

I thought about using numpy array to get a boolean array and then use list.index. The problem is that it returns the index of the first occurance. Any ideas?

Upvotes: 4

Views: 4879

Answers (3)

Graipher
Graipher

Reputation: 7186

Use numpy.where to get an array containing the indices where the condition is true and then use numpy.random.choice to randomly choose one:

import numpy as np
# to always get the same result
np.random.seed(42)

# setup data
images = np.arange(10)
labels = np.arange(10)

# select on the labels
indices = np.where(labels % 2 == 0)[0]
print(indices)
# [0, 2, 4, 6, 8]

# choose one
random_image = images[np.random.choice(indices)]
print(random_image)
# 6

You probably want to put that in a function:

from numpy import where
from numpy.random import choice

def random_img_with_label(images, labels, label):
    indices = where(labels == label)[0]
    return images[choice(indices)]

Alternatively you can directly create a mask from your condition and choose from that:

random_image = np.random.choice(images[labels % 2 == 0])

Upvotes: 11

Rolf of Saxony
Rolf of Saxony

Reputation: 22443

Is there some reason that you can't use the random function?
i.e.

>>> import random
>>> labels=['label 1','label 2','label 3','label 4']
>>> images=['image1.png','image2.png','image3.png','image4.png','image5.png','image6.png']
>>> for i in labels: print(random.choice(images))
... 
image2.png
image4.png
image3.png
image3.png
>>> 

Upvotes: -1

user2988908
user2988908

Reputation:

There is one, and only one, obvious way to do this; and that is to use random.choice. Here's a link to the documentation.

If there is a filter that you want to apply to your datasets, you might consider using a list comprehension.

Here's what I mean:

import random

image_list = [ "image0"
             , "image1"
             , "image2"
             , "image3"
             , "image4"
             , "image5"
             , "image6"
             ]

label_list = [ "labelA"
             , "labelB"
             , "labelC"
             , "labelA"
             , "labelB"
             , "labelC"
             , "labelA"
             ]

print random.choice([img for (img, lbl) in zip(image_list, label_list) if lbl == "labelA"])

List using the standard library and comprehensions are more pythonic than "rolling your own" random selector.

Upvotes: 0

Related Questions