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)
6条答案
按热度按时间o2gm4chl1#
获得期望输出的更简单的方法是在上限中添加步长。比如说
也可以让你包括终点。在您的案例中:
会导致
p3rjfoxz2#
更新2023-04-21
修复了
stop
-start
为step
s =〉的非整数的代码中的错误简称/ TLDR
意外行为:
修复:
背景信息
我也遇到过你的问题。我通常通过添加一个小值来快速修复它。正如Kasrâmvd在评论中提到的,这个问题有点复杂,因为numpy中可能会发生浮点舍入错误。arange(参见here和here)。
意外行为可在本例中找到:
为了让我自己清楚一点,我决定对np.arange非常小心。
代码
arange_cust.py
:Pytests
为了避免将来出现错误,这里有一个测试模块。如果我们再次找到一些东西,让我们添加一个测试用例。
test_arange_cust.py
:dohp0rv53#
有趣的是,你得到了这样的输出。运行
arange(0.0,0.6,0.2)
得到:无论如何,从
numpy.arange
文档:* 值是在半开区间[开始,停止]内生成的(换句话说,包括开始但不包括停止的区间)。也来自docs: 当使用非整数步长时,例如0。1、结果往往会不一致。对于这些情况,最好使用
numpy.linspace
*我唯一可以建议的是,要达到你想要的效果,修改stop参数,增加一个非常小的量,例如
退货
这是你想要的输出。
无论如何,最好使用
numpy.linspace
并设置endpoint=True
vs3odd8k4#
老问题,但它可以做得更容易。
它给出了
jslywgbw5#
一个使用
np.linspace
的简单示例(在其他答案中多次提到,但没有给出简单示例):假设:
stop
是step
的倍数。round
是纠正浮点错误所必需的。2fjabf4q6#
好吧,我把这个解决方案留在这里。第一步是计算给定边界
[a,b]
和step
数量的项目数的小数部分。接下来,计算一个适当的数量,添加到末尾,不会影响结果numpy数组的大小,然后调用np.arrange()
。图纸:
如果你想把它压缩成一个函数: