Как нарезать, начиная с отрицательного до положительного индекса или наоборот - PullRequest
1 голос
/ 29 апреля 2020

Numpy не может выполнить следующую индексацию:

a = np.arange(10)
a[-2: 2]

В настоящее время я делаю это не очень элегантно, есть ли хитрость или единый способ получить это?

РЕДАКТИРОВАТЬ: обратите внимание, что я не знаю, сталкиваюсь ли я с этим сценарием в моем коде, это иногда случается, поэтому я ищу динамическое c и универсальное решение, а не что-то для этого только в точном случае.

РЕДАКТИРОВАТЬ: мой обобщенный слайсер, довольно длинный.

def slicer(array, lower_, upper_):
    n = len(array)
    lower_ = lower_ % n  # if negative, you get the positive equivalent. If > n, you get principal value.
    roll = lower_
    lower_ = lower_ - roll
    upper_ = upper_ - roll
    array_ = np.roll(array, -roll)
    upper_ = upper_ % n
    return array_[lower_: upper_]

Ответы [ 3 ]

1 голос
/ 29 апреля 2020
In [71]: slicer(np.arange(10),-2,2)                                                                    
Out[71]: array([8, 9, 0, 1])

Похоже, np.r_ выполняет тот тип «броска», который вам нужен:

In [72]: np.arange(10)[np.r_[-2:2]]                                                                    
Out[72]: array([8, 9, 0, 1])
In [73]: np.r_[-2:2]                                                                                   
Out[73]: array([-2, -1,  0,  1])

Могут быть различия между тем, что вы ожидаете, и тем, что делает r_. Я позволю вам изучить его документы.

Просто потому, что вы называете это нарезкой, это не basic индексация. Как бы то ни было, результатом является copy, а не view. И остерегайтесь любого вида расширения многомерной индексации.

Будьте осторожны при поиске замены на все случаи жизни. Использование отрицательного индекса для отметки с конца, без переноса, настолько глубоко внедрено в Python и numpy, что вы всегда должны предполагать, что это поведение по умолчанию.

In [77]: np.arange(10)[-2:2]                                                                           
Out[77]: array([], dtype=int64)

Рассматривайте ваш упакованный / свернутый футляр как исключение, одно из которых требует особой обработки.

0 голосов
/ 29 апреля 2020

Учитывая, что вы знаете длину, вы можете просто добавить длину вашего массива к нижнему и верхнему, если они <0. Затем вы можете проверить, является ли верхний меньше нижнего, и объединить, если необходимо. </p>

def slicer(a, lower, upper):
    if lower < 0:
        lower += len(a)
    if upper < 0:
        upper += len(a)
    if upper < lower:
        return np.concatenate([a[lower:], a[:upper]])
    return a[lower:upper]

0 голосов
/ 29 апреля 2020
def slicer(a, lower, upper):
    if lower < 0:
        return np.concatenate((a[lower:], a[:upper]))
    else:
        return a[lower: upper]

Я думаю, это относительно просто.

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