5

My final goal is to use a vectorized numpy solution for a for-loop. This loop creates for each element a random sample from another list if its elements are not given in the original element. However, the for-loops' input is a list of lists. I do not know how to apply a numpy vectorization for a list of lists. A reproducible example is here:

import random

list_of_all_items = [1, 2, 3, 4, 12, 21, 23, 42, 93]
seen_formats = [[1, 2, 3, 4], [2,23, 21, 3], [12, 42, 93, 1]]


not_seen_formats = []
for seen in seen_formats:
    not_seen_formats.append(random.sample([format_ for format_ in list_of_all_items if format_ not in seen],
                            len(seen) * 1))

What I tried so far is:

import numpy as np

np.where(np.in1d(np.random.choice(list_of_all_items, 2, replace = False), np.asarray(seen_formats)))
>> (array([0, 1], dtype=int64),)

This sadly makes no sense. What I would like to have returned is an array which should contain random samples for the given list of lists, like:

>> array([[12, 21], # those numbers should be random numbers
          [ 1,  4],
          [ 2,  3]])
2
  • Can we assume a shape for seen_formats or does each of its rows potentially have a different number of elements? Commented Feb 2, 2021 at 18:15
  • The shape of seen_formats can change in its size. Even the lists list elements can vary. However, the answer pointed out here works fine. Commented Feb 3, 2021 at 10:36

1 Answer 1

1
import numpy as np
np.random.seed(42)

list_of_all_items = np.array([1, 2, 3, 4, 12, 21, 23, 42, 93])
seen_formats = np.array([[1, 2, 3, 4], [2,23, 21, 3], [12, 42, 93, 1]])

print(list_of_all_items, '\n')
print(seen_formats, '\n')

def select(a, b):
    return np.random.choice(a=np.setdiff1d(b, a), size=a.size, replace=False)

selection = np.apply_along_axis(func1d=select, axis=1, arr=seen_formats, b=list_of_all_items)
print(selection)

# Alternatively:
# select_vect = np.vectorize(select, excluded=['b'], signature='(m),(n)->(m)')
# selection2  = select_vect(seen_formats, list_of_all_items)
# print(selection2)

Output:

[ 1  2  3  4 12 21 23 42 93] 

[[ 1  2  3  4]
 [ 2 23 21  3]
 [12 42 93  1]] 

[[21 93 23 12]
 [42  4 12  1]
 [ 3  2 21 23]] 
Sign up to request clarification or add additional context in comments.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.