Suppose I want to create a set of float numbers starting from 0.1 to 0.00001 as first diving by two and then diving by 5. In other words, I'd like to get the numbers shown below.
0.1
0.05
0.01
0.005
0.001
0.0005
0.0001
0.00005
0.00001
For this small example, I wrote the following code snippet which works fine.
import numpy as np
def format_float(num):
return np.format_float_positional(num, trim='-')
num = 0.1
for j in range(9):
if j ==0:
rate=np.round(num*(0.1),j+1)
print(format_float(num))
elif ( (j+1) % 2) != 0:
num=np.round(num*(0.2),j+1)
print(format_float(num))
else:
num =np.round(num/2,j+1)
print(format_float(num))
My question is if there is a more elegant way to perform this operation given different rules. For instance, suppose I would like to get the number between x
and y
where the rule is to first divide by k
and then divide by l
in order. I believe this should be managable through linspace
, but I could not do it.
In [1]: import numpy as np
In [2]: np.repeat(1 / 10**np.arange(1, 5), 2)[1:] * np.array([1., 5.]*4)[:-1]
Out[2]: array([0.1 , 0.05 , 0.01 , 0.005 , 0.001 , 0.0005, 0.0001])
Generalizing for any "pattern":
def rates(smallest_magnitude, pattern):
n = len(pattern)
pows = np.repeat(1 / 10**np.arange(1, smallest_magnitude), n)[(n-1):]
mults = np.array(pattern * (smallest_magnitude - 1))[:-(n-1)]
return np.round(pows * mults, smallest_magnitude)
Demo:
In [4]: print(*rates(5, [1, 5])) # Your original 'pattern'
0.1 0.05 0.01 0.005 0.001 0.0005 0.0001
In [5]: print(*rates(5, [2, 4, 8]))
0.2 0.04 0.08 0.02 0.004 0.008 0.002 0.0004 0.0008 0.0002
In [6]: print(*rates(5, [3, 5, 7, 9]))
0.3 0.05 0.07 0.09 0.03 0.005 0.007 0.009 0.003 0.0005 0.0007 0.0009 0.0003