0

I have generated random numbers in a certain range before sorting it:

A = []
for _ in range(10000):
    value = np.random.randint(60,100)
    A.append(value)
A = sorted(A)

But what I want to do is to obtain a list of A that is sorted like the sine graph (with peaks and valleys). So essentially the values should be sorted in a manner where it gradually rises and falls with valleys at 60 and peaks at 100.

I am trying to create very simple mock data simulating heart rate. I have thought about using sort using a custom key but I don't know where to start. I've also looked into Faker but I don't think I can achieve the generated data I wanted with it (correct me if I'm wrong!)

Totally up for different solutions for this problem. Thanks in advance!

Serena
  • 75
  • 7
  • 1
    I'd just generate a sine wave and use a noise library to change the wave up a bit. – tkausl Oct 16 '21 at 23:10
  • Here is something that could be of some help [Robust peak detection algorithm (using z-scores)](https://stackoverflow.com/a/22640362/10915018) Seems like there is a lot of information here – ConnerWithAnE Oct 16 '21 at 23:12
  • You can't sort a single list like this, but you can create a bunch of sub-lists and alternate between sorting them in ascending vs descending order. I agree with the approach of starting with a sine wave and adding noise to it, though. – Samwise Oct 16 '21 at 23:13
  • @tkausl Hi! thanks for replying! Sorry if this is a noobie question but by generating a sine wave, do you mean something like numpy.sin()? I've tried something similar but can't seem to get the values in the range I am looking for or in the same order as the wave. – Serena Oct 16 '21 at 23:20
  • @samwise Thank you for replying! Added a question in my reply to the user who mentioned the sine wave approach! – Serena Oct 16 '21 at 23:21
  • 1
    @FivePlyPaper thank you so much, I'll definitely give it a read! – Serena Oct 16 '21 at 23:21

1 Answers1

0

One possibilitie is to generate random phases, meaning the arguments for the sin function. You have to decide first how many cycles you want (there are one valley and one peak for each cycle). If you want CY cycles then you have to generate numbers in the range (0, N * 2 * pi).

Then sort the phases and last apply the sin function to the phases.

import numpy as np
CY = 8
ph = np.random.rand(800) * CY * 2 * np.pi
ph.sort()
A = np.sin(ph)

# then you can plot the numbers, for example
from matplotlib import pyplot as plt
plt.plot(A)
plt.show()

enter image description here

the function call np.random.rand(800) generate 800 random numbers in the interval (0,1), so you have to multiply it to obtain the desired interval.

If you use too many numbers, the result is undistinguishable from a sin function.

Another posibilitie is start with a sin function and then add random numbers:

N = 800; CY = 8; DEV = 0.3
sin = np.sin(np.linspace(0, CY*2*np.pi, N)) 
A = sin + np.random.rand(N) * DEV

enter image description here

Also you can try changing the sin function for another

nadapez
  • 2,603
  • 2
  • 20
  • 26