5

Can you create a numpy array with all unique values in it?

myArray = numpy.random.random_integers(0,100,2500)
myArray.shape = (50,50)

So here I have a given random 50x50 numpy array, but I could have non-unique values. Is there a way to ensure every value is unique?

Thank you

Update:

I have created a basic function to generate a list and populate a unique integer.

        dist_x = math.sqrt(math.pow((extent.XMax - extent.XMin), 2))
        dist_y = math.sqrt(math.pow((extent.YMax - extent.YMin),2))
        col_x = int(dist_x / 100)
        col_y = int(dist_y / 100)
        if col_x % 100 > 0:
            col_x += 1
        if col_y % 100 > 0:
            col_y += 1
        print col_x, col_y, 249*169
        count = 1
        a = []

        for y in xrange(1, col_y + 1):
            row = []
            for x in xrange(1, col_x + 1):
                row.append(count)
                count += 1
            a.append(row)
            del row

        numpyArray = numpy.array(a)

Is there a better way to do this?

Thanks

3
  • 4
    You seem to be asking for 2500 unique random integers between 0 and 100. It should be pretty obvious why that's not going to happen...
    – ali_m
    Commented Aug 18, 2014 at 17:44
  • I was asking if there was a built in method or a fast way to do this? Commented Aug 18, 2014 at 17:59
  • 1
    Do you need random numbers, or just unique? If just unique, maybe np.random.permutation(np.arange(N))?
    – ojy
    Commented Aug 18, 2014 at 18:04

2 Answers 2

11

The most convenient way to get a unique random sample from a set is probably np.random.choice with replace=False.

For example:

import numpy as np

# create a (5, 5) array containing unique integers drawn from [0, 100]
uarray = np.random.choice(np.arange(0, 101), replace=False, size=(5, 5))

# check that each item occurs only once
print((np.bincount(uarray.ravel()) == 1).all())
# True

If replace=False the set you're sampling from must, of course, be at least as big as the number of samples you're trying to draw:

np.random.choice(np.arange(0, 101), replace=False, size=(50, 50))
# ValueError: Cannot take a larger sample than population when 'replace=False'

If all you're looking for is a random permutation of the integers between 1 and the number of elements in your array, you could also use np.random.permutation like this:

nrow, ncol = 5, 5
uarray = (np.random.permutation(nrow * ncol) + 1).reshape(nrow, ncol)
2
  • So if I know the number of columns/rows I should be able to do this? numpyArray = numpy.random.choice(numpy.arange(1, (col_x*col_y)+1), replace=0, size=(col_x, col_y)). This should lead to me getting the correct size with allowed unique values in each column/row location in the matrix. Commented Aug 18, 2014 at 18:18
  • Well, if you just want a random permutation of the elements in the (inclusive) range [1, col_x * col_y], you might as well just use (np.random.permutation(col_x * col_y) + 1).reshape(col_x, col_y), as I think @oja was hinting.
    – ali_m
    Commented Aug 18, 2014 at 18:22
0

Just use replace = False.

import numpy as np


def generate():
    global x
    powerball = np.random.randint(1,27)
    numbers = np.random.choice(np.arange(1, 70), replace=False, size=(1, 5))
    x = numbers, powerball
    return x

generate()

Your Answer

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

Not the answer you're looking for? Browse other questions tagged or ask your own question.