5

Using only the QGIS field calculator, how to create an expression that generates random numbers without duplicates?

rand (1,10) and randf (1,10) generate random numbers but could be repeated in a set of 10 records.

this expression generates 10 random numbers without duplicates

array_distinct (array_agg (expression: = rand (1,10))

but it's an array I need a single number for each record.

9
  • This more of a Stack Overflow question than GIS SE, but should be simple enough to create a list with 10 elements and use a random generator to choose an integer in the range [0...len(l)-1], then destructively read that element from the list. If len(1) == 1, just return the last element and reinitialize the list.
    – Vince
    Apr 11, 2019 at 22:33
  • 1
    Does creating a custom python function counts? Apr 12, 2019 at 6:47
  • 1
    What is your use case? And you mean you need a column with random numbers that are unique for each feature? Apr 12, 2019 at 6:48
  • 1
    I would add a random number from 1 to 1000 in a column, order that, then do a loop giving 1,2,3... Until 10. And start back at 1 again. Apr 12, 2019 at 13:27
  • 1
    @pigreco - How about an expression like: array_get(array_distinct(array_agg (rand(0, count($id)))), $id)
    – Joseph
    Apr 12, 2019 at 15:36

1 Answer 1

7

As @AlexandreNeto mentioned, you could create a custom python function in the Field Calculator which creates a range list of values based on the feature count of your active layer. The list is then shuffled and you can extract a unique id value randomly.

You could use something like the following script:

from qgis.core import *
from qgis.gui import *
import random

layer = qgis.utils.iface.activeLayer()
ids = list(range(1, layer.featureCount() + 1))
random.shuffle(ids)

@qgsfunction(args='auto', group='Custom')
def random_id(value, feature, parent):
    return ids[value]

And then use the following as the expression:

random_id($id)

Note: You must click the Save and Load Functions button in the Function Editor before using it on other layers. This is because defining the active layer and creating the list of unique values based on its features count is outside the function in order to avoid re-creating the list each time for each row.

4
  • Joseph - I tried to use the function, here are my results: random_id ($id) on a shapefile of 100 features gives me an error (list index out of range)
    – pigreco
    Apr 17, 2019 at 7:48
  • @pigreco - Which QGIS version are you using?
    – Joseph
    Apr 17, 2019 at 9:12
  • 1
    Joseph - I did the test in QGIS 3.4.6. (in 3.6 and 3.7 master it works !!!) thank you
    – pigreco
    Apr 17, 2019 at 9:21
  • 1
    @pigreco - Most welcome, glad it works :)
    – Joseph
    Apr 17, 2019 at 9:25

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.