Python:范围或numpy带有结束限制的Arange包括

时间:2018-05-11 19:40:45

标签: python numpy

我希望得到:

输入:

arange(0.0,0.6,0.2)

输出:

0.,0.4

我想要

0.,0.2,0.4,0.6

我如何实现使用范围或范围。如果不是什么是替代?

4 个答案:

答案 0 :(得分:1)

简而言之

我写了一个函数crange,该函数可以满足您的要求。 在下面的示例中,orange完成了numpy.arange

的工作
crange(1, 1.3, 0.1) >>> [1.  1.1 1.2 1.3]
orange(1, 1.3, 0.1) >>> [1.  1.1 1.2]
crange(0.0, 0.6, 0.2) >>> [0.  0.2 0.4 0.6]
orange(0.0, 0.6, 0.2) >>> [0.  0.2 0.4]

背景信息

查看时间也遇到了您的问题。我通常通过添加一个较小的值来快速修复该错误。正如Kasrâmvd在评论中所提到的,这个问题更加复杂,因为在numpy.arange中可能会发生浮点舍入错误(请参见herehere)。

在此示例中可以找到

意外行为

>>> numpy.arange(1, 1.3, 0.1)
array([1. , 1.1, 1.2, 1.3])

为了让自己有所了解,我决定在没有特别需要的情况下停止使用numpy.arange。相反,我使用自定义函数orange来避免意外行为。这结合了numpy.isclosenumpy.linspace

以下是代码

足够了,这是代码^^

import numpy as np

def cust_range(*args, rtol=1e-05, atol=1e-08, include=[True, False]):
    """
    Combines numpy.arange and numpy.isclose to mimic
    open, half-open and closed intervals.
    Avoids also floating point rounding errors as with
    >>> numpy.arange(1, 1.3, 0.1)
    array([1. , 1.1, 1.2, 1.3])

    args: [start, ]stop, [step, ]
        as in numpy.arange
    rtol, atol: floats
        floating point tolerance as in numpy.isclose
    include: boolean list-like, length 2
        if start and end point are included
    """
    # 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)

    # determine number of segments
    n = (stop-start)/step + 1

    # do rounding for n
    if np.isclose(n, np.round(n), rtol=rtol, atol=atol):
        n = np.round(n)

    # correct for start/end is exluded
    if not include[0]:
        n -= 1
        start += step
    if not include[1]:
        n -= 1
        stop -= step

    return np.linspace(start, stop, int(n))

def crange(*args, **kwargs):
    return cust_range(*args, **kwargs, include=[True, True])

def orange(*args, **kwargs):
    return cust_range(*args, **kwargs, include=[True, False])

print('crange(1, 1.3, 0.1) >>>', crange(1, 1.3, 0.1))
print('orange(1, 1.3, 0.1) >>>', orange(1, 1.3, 0.1))
print('crange(0.0, 0.6, 0.2) >>>', crange(0.0, 0.6, 0.2))
print('orange(0.0, 0.6, 0.2) >>>', orange(0.0, 0.6, 0.2))

答案 1 :(得分:0)

好的,我会在这里留下这个解决方案。第一步是计算给定边界 [a,b]step 数量的项目数的小数部分。接下来计算适当的数量添加到最后,不会影响结果numpy数组的大小,然后调用np.arrange()

import numpy as np

def np_arange_fix(a, b, step):
    nf = (lambda n: n-int(n))((b - a)/step+1)
    bb = (lambda x: step*max(0.1, x) if x < 0.5 else 0)(nf)
    arr = np.arange(a, b+bb, step)

    if int((b-a)/step+1) != len(arr):
        print('I failed, expected {} items, got {} items, arr-out{}'.format(int((b-a)/step), len(arr), arr))
        raise

    return arr


print(np_arange_fix(1.0, 4.4999999999999999, 1.0))
print(np_arange_fix(1.0, 4 + 1/3, 1/3))
print(np_arange_fix(1.0, 4 + 1/3, 1/3 + 0.1))
print(np_arange_fix(1.0, 6.0, 1.0))
print(np_arange_fix(0.1, 6.1, 1.0))

打印:

[1. 2. 3. 4.]
[1.         1.33333333 1.66666667 2.         2.33333333 2.66666667
 3.         3.33333333 3.66666667 4.         4.33333333]
[1.         1.43333333 1.86666667 2.3        2.73333333 3.16666667
 3.6        4.03333333]
[1. 2. 3. 4. 5. 6.]
[0.1 1.1 2.1 3.1 4.1 5.1 6.1]

如果你想把它压缩成一个函数:

def np_arange_fix(a, b, step):
    b += (lambda x: step*max(0.1, x) if x < 0.5 else 0)((lambda n: n-int(n))((b - a)/step+1))
    return np.arange(a, b, step)

答案 2 :(得分:0)

获得所需输出的更简单方法是在上限中添加步长。例如,

final outputList = getList(3, your_int_list);
print(outputList); // Prints non-repeating 3 random number

也允许您包含终点。在你的情况下:

np.arange(start, end + step, step)

会导致

np.arange(0.0, 0.6 + 0.2, 0.2)

答案 3 :(得分:0)

老问题,但可以更容易。

def arange(start, stop, step=1, endpoint=True):
    arr = np.arange(start, stop, step)

    if endpoint and arr[-1]+step==stop:
        arr = np.concatenate([arr,[end]])

    return arr


print(arange(0, 4, 0.5, endpoint=True))
print(arange(0, 4, 0.5, endpoint=False))

给出

[0.  0.5 1.  1.5 2.  2.5 3.  3.5 4. ]
[0.  0.5 1.  1.5 2.  2.5 3.  3.5]