Marking duplicate entries in a numpy array as True So the problem is

Find the duplicate entries (2nd occurrence onwards) in the given numpy
array and mark them as True. First time occurrences should be False.

And my solution is:
import numpy as np


def duplicates(a):
    uniques = np.unique(a)
    result = []
    for i in a:
        if i not in uniques:
            result.append(True)
        else:
            result.append(False)
            uniques = np.delete(uniques, np.where(uniques == i))
    return result


np.random.seed(100)
a = np.random.randint(0, 5, 10)
print('Array: ', a)
print(duplicates(a))

What improvments can i make in this program?
As mentioned in the comments of another answer, you should use sets for membership tests whenever possible. Combinig this with building up uniques instead of cutting it down, we get this really simple implementation:
def duplicates(numbers):
    uniques = set()
    result = []

    for num in numbers:
        result.append(num in uniques)
        uniques.add(num)

    return result

This implementation of duplicates is concise, easy to read and runs in O(n) instead of O(n^2), which is a major difference. One-liners are a fun exercise that can teach you some interesting aspects of Python, and I understand their appeal, but they're often not the best way to go. It's not worth sacrificing readability and performance for the sake of writing less lines of code.

EDIT: Performance testing
As requested in the comments I tested the performance of three different approaches:
def duplicates_set(numbers):
    uniques = set()
    result = []

    for num in numbers:
        result.append(num in uniques)
        uniques.add(num)

    return result


def duplicates_list(numbers):
    result, uniques = [], []
    for elem in numbers:
        if elem in uniques:
            result.append(True)
        else:
            result.append(False)
            uniques.append(elem)

    return result


def duplicates_oneliner(numbers):
    return [elem in numbers[:i] for i, elem in enumerate(numbers)]

Note that the following approach for duplicates_list should be avoided in any case, since it checks for elem membership in uniques twice.
def duplicates_list(numbers):
    result, uniques = [], []
    for elem in numbers:
        result.append(elem in uniques)
        if elem not in uniques:
            uniques.append(elem)

    return result


Here is my code for performance testing using the timeit module. All the provided outputs were produced by this code.
num_range: (int, int)
random_nums: int
executions: int

np.random.seed(100)
a = np.random.randint(*num_range, random_nums)

from timeit import timeit

print(f&quot;{executions} executions with {random_nums} random numbers in range {num_range}&quot;)
print(&quot;duplicates_set:&quot;, &quot;\t&quot; * 2, timeit(stmt=lambda: duplicates_set(a), number=executions))
print(&quot;duplicates_list:&quot;, &quot;\t&quot; * 2, timeit(stmt=lambda: duplicates_list(a), number=executions))
print(&quot;duplicates_oneliner:\t&quot;, timeit(stmt=lambda: duplicates_oneliner(a), number=executions))

Starting out with 100_000 executions with the parameters from the original question we get this result:
100000 executions with 10 random numbers in range (0, 5)
duplicates_set:          0.22261620000000001
duplicates_list:         0.18974730000000006
duplicates_oneliner:     2.9783912

We can clearly see that the list implementation performs the best for a small amount of numbers and a small range of random numbers. The one-liner is already at a huge disadvantage.
Upping the length of the random number array to 1_000, we get this result:
1000 executions with 1000 random numbers in range (0, 5)
duplicates_set:          0.1603748
duplicates_list:         0.13001250000000003
duplicates_oneliner:     3.1837349

It seems the length of the array alone does not really affect the relative performance of duplicates_set and duplicates_list. As long as the range of numbers is small, the list comes out on top. Relative performance stayed the same up until 1_000_000 elements, which makes sense since the size of uniques is capped by the range of numbers.
Once we start increasing num_range, the set implementation really starts to shine, since it simply does not care about the size of uniques when it comes to runtime:
1000 executions with 1000 random numbers in range (0, 10)
duplicates_set:          0.15972010000000003
duplicates_list:         0.15932980000000002
duplicates_oneliner:     3.1950098

For a range of (0, 10), set and list implementation perform about the same.
At a range of (0, 1_000) the list implementation is already outperformed by the one-liner:
1000 executions with 1000 random numbers in range (0, 1000)
duplicates_set:          0.15644170000000002
duplicates_list:         3.4406095
duplicates_oneliner:     3.1854200999999995

The one-liner however is immediately out of the competition once the input gets larger, even at small number ranges:
10 executions with 100000 random numbers in range (0, 10)
duplicates_set:          0.1576303
duplicates_list:         0.24761889999999998
duplicates_oneliner:     30.1282213

The final result is exactly what would be expected:

duplicates_list really starts to struggle once the number of unique numbers goes up, since if elem in uniques gets increasingly expensive.
duplicates_oneliner completely breaks down with long input lists, since elem in numbers[:i] gets expensive really fast.
duplicates_set is only outperformed at a low number of unique numbers, but at scale it outperforms both other implementations by a huge margin, since if elem in uniques can be checked in constant time.