由于numpy.arange()使用ceil((stop - start)/step)
来确定项目数,因此小浮点数不精确(stop = .400000001)
会向列表中添加非预期值。
第一种情况不包括停止点(预期)
>>> print(np.arange(.1,.3,.1))
[0.1 0.2]
第二种情况包括停止点(非预期)
>>> print(np.arange(.1,.4,.1))
[0.1 0.2 0.3 0.4]
numpy.linspace()解决了这个问题np.linspace(.1,.4-.1,3)
。但需要知道步骤的数量。 np.linspace(start,stop-step,np.ceil((stop-step)/step))
导致同样的不满。
如何在不知道范围内的元素数量的情况下生成可靠的float
范围?
考虑我想要生成未知精度的浮点索引的情况
np.arange(2.00(...)001,2.00(...)021,.00(...)001)
答案 0 :(得分:2)
如果使用精确数学计算了这些值,您的目标是计算ceil((stop - start)/step)
。
如果{strong}仅浮点值为start
,stop
和step
,那么这是不可能的,这些值是某些舍入操作的结果可能发生了错误。舍入会删除信息,而根本无法通过缺少信息来创建信息。
因此,如果您有关于start
,stop
和step
的其他信息,则此问题仅可解决。
假设step
是准确的,但start
和stop
有一些由e0
和e1
限制的累积错误。也就是说,您知道start
最多e0
远离其理想数学值(在任一方向上),stop
最多e1
远离其理想值(在任何一个方向)。那么(stop-start)/step
的理想值可以从(stop-start-e0-e1)/step
到(stop-start+e0+e1)/step
远离其理想值。
假设(stop-start-e0-e1)/step
到(stop-start+e0+e1)/step
之间有一个整数。那么就不可能知道理想的ceil
结果应该是较小的整数,还是从start
,stop
和step
的浮点值得到的更大的结果。边界e0
和e1
。
但是,根据您提供的示例,理想(stop-start)/step
可能正好是整数,如(.4-.1)/.1
中所示。如果是这样,任何非零错误界限都可能导致错误区间跨越一个整数,使得问题无法从我们迄今为止的信息中解决。
因此,为了解决问题,您必须拥有的信息不仅仅是错误的简单边界。例如,您必须知道(stop-start)/step
正好是整数或以其他方式量化。例如,如果您知道步数的理想计算将产生.1的倍数,例如3.8,3.9,4.0,4.1或4.2,但从不4.05,并且误差足够小以至于浮动 - 点数计算(stop-start)/step
的最终误差小于.05,然后可以将(stop-start)/step
舍入到最近的符合条件的倍数,然后将ceil
应用于该值。
如果您有此类信息,可以使用start
,stop
和step
(例如)中的错误更新问题。也许它们中的每一个都是从十进制到浮点的单个转换的结果)和理想(stop-start)/step
的可能值。如果您没有此类信息,则无法解决。
答案 1 :(得分:0)
如果您保证(stop-start)
是step
的倍数,那么您可以使用decimal
模块来计算步数,即
from decimal import Decimal
def arange(start, stop, step):
steps = (Decimal(stop) - Decimal(start))/Decimal(step)
if steps % 1 != 0:
raise ValueError("step is not a multiple of stop-start")
return np.linspace(float(start),float(stop),int(steps),endpoint=False)
print(arange('0.1','0.4','0.1'))
答案 2 :(得分:0)
如果您准确表示了您的结束和步骤,如果它们是理性的,您可以使用fractions
模块:
>>> from fractions import Fraction
>>>
>>> a = Fraction('1.0000000100000000042')
>>> b = Fraction('1.0000002100000000002')
>>> c = Fraction('0.0000000099999999998') * 5 / 3
>>>
>>> float(a) + float(c) * np.arange(int((b-a)/c))
array([1.00000001, 1.00000003, 1.00000004, 1.00000006, 1.00000008,
1.00000009, 1.00000011, 1.00000013, 1.00000014, 1.00000016,
1.00000018, 1.00000019])
>>>
>>> eps = Fraction(1, 10**100)
>>> b2 = b - eps
>>> float(a) + float(c) * np.arange(int((b2-a)/c))
array([1.00000001, 1.00000003, 1.00000004, 1.00000006, 1.00000008,
1.00000009, 1.00000011, 1.00000013, 1.00000014, 1.00000016,
1.00000018])
如果不是,你将不得不接受某种形式的截止:
>>> a = 1.0
>>> b = 1.003999999
>>> c = 0.001
>>>
# cut off at 4 decimals
>>> round(float((b-a)/c), 4)
4.0
# cut off at 6 decimals
>>> round(float((b-a)/c), 6)
3.999999
答案 3 :(得分:-1)
您可以使用format
函数在Python中将数字舍入到任意精度。
例如,如果您希望小数点后的e
的前三位数字,则可以运行
float(format(np.e, '.3f'))
使用它来消除浮动不精确,你应该去。