Python: Range или Numpy Arange с конечным пределом включают - PullRequest
0 голосов
/ 11 мая 2018

Я хочу получить:

ввод:

arange(0.0,0.6,0.2)

вывод:

0.,0.4

Я хочу

0.,0.2,0.4,0.6

как сделатья достигаю с помощью диапазона или аранжировки.Если нет, то что альтернатива?

Ответы [ 2 ]

0 голосов
/ 02 августа 2019

Короче говоря

Я написал функцию 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 (см. здесь и здесь ).

Неожиданное поведение можно найти в этом примере:

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

Чтобы прояснить ситуацию для себя, я решил прекратить использование numpy.arange если не требуется специально.Вместо этого я использую свою собственную функцию orange, чтобы избежать неожиданного поведения.Это объединяет numpy.isclose и numpy.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))
0 голосов
/ 11 мая 2018

Интересно, что вы получите этот вывод.Запуск arange(0.0,0.6,0.2) Я получаю:

array([0. , 0.2, 0.4])

Независимо от numpy.arange документов: Значения генерируются в пределах полуоткрытого интервала [start, stop) (другими словами, интервал, включающийначало, но без остановки) .

Также из документов: При использовании нецелого шага, такого как 0,1, результаты часто не будут согласованными.Для этих случаев лучше использовать numpy.linspace

Единственное, что я могу предложить для достижения того, чего вы хотите, - это изменить параметр stop и добавить очень небольшое количество, например

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

Возвращает

array([0. , 0.2, 0.4, 0.6])

Какой желаемый результат.

В любом случае, лучше использовать numpy.linspace и установить endpoint=True

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...