import numpy as np
def np_arange_cust(
*args, rtol: float=1e-05, atol: float=1e-08, include_start: bool=True, include_stop: bool = False, **kwargs
):
"""
Combines numpy.arange and numpy.isclose to mimic open, half-open and closed intervals.
Avoids also floating point rounding errors as with
>>> np.arange(1, 1.3, 0.1)
array([1., 1.1, 1.2, 1.3])
Parameters
----------
*args : float
passed to np.arange
rtol : float
if last element of array is within this relative tolerance to stop and include[0]==False, it is skipped
atol : float
if last element of array is within this relative tolerance to stop and include[1]==False, it is skipped
include_start: bool
if first element is included in the returned array
include_stop: bool
if last elements are included in the returned array if stop equals last element
kwargs :
passed to np.arange
Returns
-------
np.ndarray :
as np.arange but eventually with first and last element stripped/added
"""
# process arguments
if len(args) == 1:
start = 0
stop = args[0]
step = 1
elif len(args) == 2:
start, stop = args
step = 1
else:
assert len(args) == 3
start, stop, step = tuple(args)
arr = np.arange(start, stop, step, **kwargs)
if not include_start:
arr = np.delete(arr, 0)
if include_stop:
if np.isclose(arr[-1] + step, stop, rtol=rtol, atol=atol):
arr = np.c_[arr, arr[-1] + step]
else:
if np.isclose(arr[-1], stop, rtol=rtol, atol=atol):
arr = np.delete(arr, -1)
return arr
def np_arange_closed(*args, **kwargs):
return np_arange_cust(*args, **kwargs, include_start=True, include_stop=True)
def np_arange_open(*args, **kwargs):
return np_arange_cust(*args, **kwargs, include_start=True, include_stop=False)
7条答案
按热度按时间tf7tbtn21#
一种获得所需输出的更简单方法是在上限中添加步长。比如说,
也会让你把终点也包括进去在您的案例中:
将导致
vqlkdk9b2#
更新2023-04-21
修复了
stop
-start
为step
s =>的非整数的代码中的错误简而言之/ TLDR
意外行为:
修复:
背景信息
你的问题我也遇到过几次。我通常通过添加一个小值来快速修复它。正如Kasrâmvd在评论中提到的,这个问题有点复杂,因为浮点舍入错误可能发生在numpy.arange中(参见here和here)。
意外行为可以在这个例子中找到:
为了让我自己清楚一点,我决定对np.arange非常小心。
代码
arange_cust.py
:Pytests
为了避免将来的错误,这里有一个测试模块。如果我们再次找到一些东西,让我们添加一个测试用例。
test_arange_cust.py
:mrzz3bfm3#
有趣的是,你得到了这样的输出。运行
arange(0.0,0.6,0.2)
得到:从
numpy.arange
文档来看:* 值是在半开区间[开始,停止](即包含开始但不包含停止的区间)内生成的 。也来自docs: 当使用非整数步长(如0.1)时,结果往往不一致。对于这些情况,最好使用
numpy.linspace
*我能建议的唯一一件事就是修改stop参数,增加一个非常小的量,例如
返回
这是你想要的输出。
无论如何,最好使用
numpy.linspace
并设置endpoint=True
f5emj3cl4#
老问题,但它可以做得更容易。
这给
i34xakig5#
一个使用
np.linspace
的简单示例(在其他答案中多次提到,但没有简单的示例):假设:
stop
是step
的倍数。round
是纠正浮点错误所必需的。o4tp2gmn6#
好吧,我把这个解决方案留在这里。第一步是计算给定边界
[a,b]
和step
数量的项目数的小数部分。接下来,计算一个适当的量添加到末尾,这不会影响结果numpy数组的大小,然后调用np.arrange()
。图纸:
如果你想把它压缩成一个函数:
cwtwac6a7#
当输入结束值比输入步骤更容易时,我这样做: