3

I have shapefile that includes 49 points (wells). I want to create 100 networks that include 20 randomly selected points from first network. When I used create random point tool, Some networks were duplicates. How can I create non-repetitive networks?

1
  • If you choose 100 random sets of 20 from a pool of 49, you have a non-trivial chance of generating a duplicate set. With 49!/20!x29! combinations (28277527346376) available, you cant generate all the sets to pick from, so you'll need to check the selected values against previously selected sets. The good news is that choosing sets is really easy in Python, and detecting duplicates is easy. The bad news is I won't have time to work on it soon. But look at random.shuffle then clip the set to the first 20, sort, then compare to existing sets before making outputs.
    – Vince
    Aug 25, 2021 at 10:52

2 Answers 2

4

Since we need to compile a list of IDs for an SQL IN operator anyway, let's use that string as the comparison basis to generate the unique lists...

import random
import arcpy

numSets   = 100
setSize   = 20
sourceFC  = r'D:\gis_se\pick49.shp'
outputGDB = r'D:\gis_se\picked.gdb'

# Extract all IDs
rawIDs = sorted([row[0] for row in arcpy.da.SearchCursor(sourceFC,'OID@')])

# Compile unique sets
resultSets = []
while (len(resultSets) < numSets):
    candidate = list(rawIDs)
    random.shuffle(candidate)
    subset = ','.join([str(id) for id in sorted(candidate[:setSize])])
    if (subset not in resultSets):
        resultSets.append(subset)

# Export the copies to GDB (or not)
print("\n".join(sorted(resultSets)))

When testing with "generate 10 sets with 5 picked from 10" I was able to generate duplicate candidates, but when I moved up to "generate 100 sets with 20 picked from 49" I wasn't, but even if your random generator is cruel, this won't generate duplicates.

6
  • Nice! I was thinking if resultsSets is actually a set() object you could do away with the test of if it is in the set?
    – Hornbydd
    Aug 25, 2021 at 23:38
  • Yes, that would work, but I had check code to trap for duplicates, and didn't bother to rewrite it.
    – Vince
    Aug 25, 2021 at 23:48
  • @Vince. dear Vince how to make each set of resultSets into Tuple . actually i want to make feature point with each one of this Tuple with make_feature_layer_management? i appreciate your help Aug 26, 2021 at 14:27
  • That code is in GIS SE dozens of times already, and each one seemingly different, since there are so many ways to accomplish it. I was heading toward using SelectLayerByAttributes/FeatureClassToFeatureClass, but MakeFeatureLayer could work, depending on your plan. The WHERE clause is just "FID in ({:s})".format(resultSet) for each resultSets element.
    – Vince
    Aug 26, 2021 at 16:03
  • 1
    If you can't implement an ArcPy solution from here, then you might be better off implementing the solution by @Hornbydd and just checking for duplicates before going further.
    – Vince
    Aug 26, 2021 at 18:21
2

Here is an alternative approach in ModelBuilder requiring almost no code that creates the random subsets:

The Data:

Data

The Model:

Model

The results (from just 5 iterations as way of an example):

enter image description here

The key to this model is using the point data itself as a constraint and seeding the random number generator on each iteration. Note that the output of the calculate value tool is a precondition as well as the seed environment setting for the random number generator.

  1. The FOR iterator was simply set to count from 1 to 5

  2. Calculate Value is set up as shown:

Calculate Value tool

  1. The create random points is set up as shown:

Create random points tool

I suspect that this approach as @Vince has hinted at will potentially generate identical sets, as with any other approach you may take, something you need to check? There is the Feature Compare tool that could be used to compare datasets.

2
  • Hi. is there a way to save each network with name (Value) instead of for example your (fc_%Vlaue%) Sep 12, 2021 at 14:26
  • 1
    You can save if what ever you want but you will need to include %Value% as that is what gives the output name its uniqueness, so you could replace fc_%Value% with for example random_point_set_%Value%_year2021.
    – Hornbydd
    Sep 12, 2021 at 15:29

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.