'How can I generate an array of float values of a given length in a given range and of a pre-defined mean value using Python [duplicate]
I ran into an issue when trying to generate jittered interstimulus intervals for an fMRI project and I couldn't find any resources online to generate these times. For those that don't know, within fMRI research, we often use fixation crosses between stimuli as baseline measures and we need these to be of varying lengths so that the presentation is surprising, but of a reliable mean, so that we can predict the length of the task.
As such, how can I get Python to generate arrays of float values of a given length in a given range and of a pre-defined mean value? As a relatively new python users, I didn't find any accessible solutions, so I figured one out and wanted to share it.
EDIT: The purpose of this post is to share a solution to the above issue. I searched for awhile and didn't find any solutions that worked for me, so I wanted to post the question with the solution I worked out incase others stumble upon it. Michael Szczesny was nice enough to point me towards an alternative solution which is more sound. While perhaps fine for the very specific purpose of generating ISIs, it is not sound for generating arrays for more general purposes. I flagged this post as a duplicate, so you should be able to find the better solution through that.
Solution 1:[1]
I wanted to share my solution, should anyone else run into this issue and not find any publicly available solutions.
## Dependencies ----
import numpy as np
import random
## Conveniently modifiable variables ----
# Completely arbitrary; just choosing values to demonstate
seed = 101
ISI_n = 100
ISI_mean = 2.000
ISI_lower = 0.500
ISI_upper = 4.000
## Function -----
def generate_jitter(seed, ISI_n, ISI_mean, ISI_lower, ISI_upper):
# A tracker to track which iteration we are currently on
tracker = 1
# A seed to be able to create the same simulation reliably
random.seed(seed)
# Creating an array to house the jitter values
jitters = []
# Iterate through this loop ISI_n times
while tracker <= ISI_n:
# If this is the first iteration
if tracker == 1:
# Add a random value with 3 digits that's between ISI_lower and ISI_upper to the array.
jitters.append(round(random.uniform(ISI_lower, ISI_upper), 3))
# If this is any other iteration
if tracker > 1:
# Calculate the value that would make the mean of array Jitters equal to ISI_mean
balance = (ISI_mean * tracker) - sum(jitters)
# Calculate how many iterations are left in this loop
progress = ((ISI_n - tracker)/ISI_n)
# Calculate an upper bound centered around the balance value, but not the balance value.
# As the loop grows closer to the final iteration, this value will be closer to the balance value.
upper = balance + ((ISI_upper - balance) * progress)
# If on the off chance upper is greater than ISI_upper
if upper > ISI_upper:
# Make upper equivalent to ISI_upper
upper = ISI_upper
lower = balance - ((balance - ISI_lower) * progress)
# If on the off chance upper is greater than ISI_upper
if lower < ISI_lower:
# Make upper equivalent to ISI_upper
lower = ISI_lower
# Then generate a new float between upper and lower
jitters.append(round(random.uniform(lower, upper), 3))
# Add 1 to the tracker in preparation for the next iteration
tracker += 1
# Randomly shuffle the array
random.shuffle(jitters)
return jitters
# Demonstrating that the function works using the values defined above.
array = generate_jitter(seed = seed,
ISI_n = ISI_n,
ISI_mean = ISI_mean,
ISI_lower = ISI_lower,
ISI_upper = ISI_upper)
print(np.mean(array))
print(np.min(array))
print(np.max(array))
print(len(array))
My output:
# Slightly off, but our MRI clock won't register
# 0.0000000000000002 seconds. This will get rounded to 2.000
# so close enough for my purposes
>>> print(np.mean(array))
1.9999999999999998
>>> print(np.min(array))
0.702
>>> print(np.max(array))
3.83
>>> print(len(array))
100
>>>
Sources
This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.
Source: Stack Overflow
| Solution | Source |
|---|---|
| Solution 1 |
