patternpythonMinor
Creating a list of new areas for patches of conserved land within a watershed
Viewed 0 times
newcreatingwatershedlandareasconservedwithinforlistpatches
Problem
I'm writing code to create a list of new areas for patches of conserved land within a watershed based on the current size distribution of conserved land patches that are in the watershed now.
I'm generating a new random area based on a normal probability density function fitted to the log-transformed distribution of the sizes of currently conserved land. Then I have a list of the areas of tax parcels in the region, and I want to randomly grab a tax parcel that is within ± 10% of the randomly generated area. The loop will continue until I've generated a total 4,735 hectares of new areas for conservation.
The code works, and runs very quickly if I lower the threshold for total new conserved area to ~500 hectares. However, for my current endpoint (4,735 new hectares), it runs so slowly that I haven't actually ever run it all the way through (waited an hour+). Any ideas on how I can streamline this code to get it to run faster are greatly appreciated!
```
# Set endpoint of total new area
new_cons_area = 4735.44
# Get new random areas until they total the new_cons_area
sum_rand_area = 0
new_rand_area = []
rand_sizes = []
index_list = []
while sum_rand_area = 3.33:
# Run this loop until a new size is added to the list of new random areas
while len(new_rand_area) == current_length:
# Grab a random index from the list of parcel areas
rand_index = random.randrange(len(parcel_areas)-1)
# See if the parcel area associated with the random index matches the randomly generated size
if min_size <= parcel_areas[rand_index] <= max_size:
# If criteria is met, add the randomly generated size to a list
rand_sizes.append(int(new_size))
# Add the randomly generated index to list so you can grab the object ids in the next step
index_list.append(rand_index)
# Add the actual tax parcel area to a list
new_rand_area.append(parcel_
I'm generating a new random area based on a normal probability density function fitted to the log-transformed distribution of the sizes of currently conserved land. Then I have a list of the areas of tax parcels in the region, and I want to randomly grab a tax parcel that is within ± 10% of the randomly generated area. The loop will continue until I've generated a total 4,735 hectares of new areas for conservation.
The code works, and runs very quickly if I lower the threshold for total new conserved area to ~500 hectares. However, for my current endpoint (4,735 new hectares), it runs so slowly that I haven't actually ever run it all the way through (waited an hour+). Any ideas on how I can streamline this code to get it to run faster are greatly appreciated!
```
# Set endpoint of total new area
new_cons_area = 4735.44
# Get new random areas until they total the new_cons_area
sum_rand_area = 0
new_rand_area = []
rand_sizes = []
index_list = []
while sum_rand_area = 3.33:
# Run this loop until a new size is added to the list of new random areas
while len(new_rand_area) == current_length:
# Grab a random index from the list of parcel areas
rand_index = random.randrange(len(parcel_areas)-1)
# See if the parcel area associated with the random index matches the randomly generated size
if min_size <= parcel_areas[rand_index] <= max_size:
# If criteria is met, add the randomly generated size to a list
rand_sizes.append(int(new_size))
# Add the randomly generated index to list so you can grab the object ids in the next step
index_list.append(rand_index)
# Add the actual tax parcel area to a list
new_rand_area.append(parcel_
Solution
The problem is that
Sort the list of areas by size. Once you determined
random.randrange(len(parcel_areas)-1) most of the times returns an area which fails the min_size <= parcel_areas[rand_index] <= max_size test. Therefore it is logical to restrict the random selection to the set of areas which satisfy the requirements beforehand, and eliminate the inner loop completely.Sort the list of areas by size. Once you determined
min_size and max_size, find corresponding bounds (with binary search), and select randomly within these bounds.Context
StackExchange Code Review Q#117655, answer score: 5
Revisions (0)
No revisions yet.