Home > front end >  how to efficiently create a range of float numbers
how to efficiently create a range of float numbers

Time:10-12

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.

CodePudding user response:

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

CodePudding user response:

This works, but I'm not sure it's any better than your method.

import numpy as np

# Create the powers of ten:
a = 0.1 ** np.arange(1,6)
# Interleave the halves in between:
a = np.concatenate((a,a/2))
# Sort and reverse: 
a.sort()
a = a[-1::-1]

print(a)

CodePudding user response:

Two ways:

>>> np.cumprod([.1]   4*[1/2, 1/5])
array([1.e-01, 5.e-02, 1.e-02, 5.e-03, 1.e-03, 5.e-04, 1.e-04, 5.e-05,
       1.e-05])
>>> 1 / np.cumprod([10]   4*[2, 5])
array([1.e-01, 5.e-02, 1.e-02, 5.e-03, 1.e-03, 5.e-04, 1.e-04, 5.e-05,
       1.e-05])
  • Related