如何有效地创建一系列浮点数
how to efficiently create a range of float numbers
假设我想创建一组从 0.1 到 0.00001 的浮点数,首先跳水 2,然后跳水 5。换句话说,我想得到如下所示的数字。
0.1
0.05
0.01
0.005
0.001
0.0005
0.0001
0.00005
0.00001
对于这个小例子,我编写了以下代码片段,效果很好。
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))
我的问题是在给定不同规则的情况下是否有更优雅的方法来执行此操作。例如,假设我想得到 x
和 y
之间的数字,规则是先除以 k
,然后按顺序除以 l
。我相信这应该可以通过 linspace
来管理,但我做不到。
这可行,但我不确定它是否比您的方法更好。
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)
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])
对任何“模式”进行概括:
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)
演示:
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
两种方式:
>>> 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])
假设我想创建一组从 0.1 到 0.00001 的浮点数,首先跳水 2,然后跳水 5。换句话说,我想得到如下所示的数字。
0.1
0.05
0.01
0.005
0.001
0.0005
0.0001
0.00005
0.00001
对于这个小例子,我编写了以下代码片段,效果很好。
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))
我的问题是在给定不同规则的情况下是否有更优雅的方法来执行此操作。例如,假设我想得到 x
和 y
之间的数字,规则是先除以 k
,然后按顺序除以 l
。我相信这应该可以通过 linspace
来管理,但我做不到。
这可行,但我不确定它是否比您的方法更好。
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)
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])
对任何“模式”进行概括:
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)
演示:
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
两种方式:
>>> 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])