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.

  • 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 '19 at 22:33
  • 1
    Does creating a custom python function counts? – Alexandre Neto Apr 12 '19 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? – spatialthoughts Apr 12 '19 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. – Alexandre Neto Apr 12 '19 at 13:27
  • 1
    @pigreco - How about an expression like: array_get(array_distinct(array_agg (rand(0, count($id)))), $id) – Joseph Apr 12 '19 at 15:36

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))

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

And then use the following as the expression:


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.

  • 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 '19 at 7:48
  • @pigreco - Which QGIS version are you using? – Joseph Apr 17 '19 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 '19 at 9:21
  • 1
    @pigreco - Most welcome, glad it works :) – Joseph Apr 17 '19 at 9:25

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

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