How could you randomly exclude/delete elements from an array that satisfy some condition?

Viewed 133

For example, if I had a 1x100 array, and it contained 90 0's, I'd like to somehow exclude 80 of those 0's chosen at random. I've been struggling with this problem for a while and I've made very little progress unfortunately.

3 Answers

Since you have a numpy tag:

import numpy as np

def solution(arr, value, size):
    return np.delete(arr, np.random.choice(np.flatnonzero(arr==value), size, False))

arr = np.array([0]*90 + [1]*10)
np.random.shuffle(arr)

print(solution(arr, 0, 80)) # [1 0 1 0 0 1 0 0 1 0 1 1 1 0 0 0 0 1 1 1]
print(solution(arr, 0, 90)) # [1 1 1 1 1 1 1 1 1 1]
print(solution(arr, 0, 100)) # Raises error (expected behavior)

Vanilla Python approach.

Determine indices of the elements meeting the criteria:

candidate_indices = [i for i, x in enumerate(data) if data == 0]

Choose indices to remove:

removed_indices = random.sample(candidate_indices, 80)

Remove them, by building a list without the corresponding elements:

result = [x for i, x in enumerate(data) if i not in removed_indices]

This is one approach, it is not very efficient, but it should be robust.

def progressivelyExcludeItem(item, arr, maxExclusions):
    """
    @param item the item value that will be progressively excluded
    @param arr the list from which we will exclude
    @param maxExclusions the maximum number of excluded items 
    """

    excludeIndices = [i for i, x in enumerate(arr) if x == item]
    excludeIndices = random.shuffle(excludeIndices)[:maxExclusions]

    for i in excludeIndices.sort().reversed():
        arr.pop(i)

Time complexity is O(n^2).

Related