Как выполнить циклический сдвиг массива numpy без копирования памяти O (n)?Python

Программы на Python
Ответить
Anonymous
 Как выполнить циклический сдвиг массива numpy без копирования памяти O (n)?

Сообщение Anonymous »

Краткая версия:
как это сделать без копирования памяти O(n)

Код: Выделить всё

    start  = 2            # \/ start points here
input  = np.array([4, 5, 1, 2, 3])
output = np.array([1, 2, 3, 4, 5]) # output doesn't need to be memory contiguous, a view is just fine
Длинная версия:
Я пытаюсь реализовать буфер FIFO фиксированной длины на основе numpy.ndarray для аппаратного моделирования.

Моя цель — добиться O(1) (или, по крайней мере, меньше, чем O(n)) постановки в очередь/удаления из очереди, и самое главное: получить массив numpy с правильным порядком.
В конечном итоге я использую указатель start указывает на первый элемент FIFO, поэтому постановка в очередь/извлечение из очереди — это всего лишь одно присваивание/индексация, что происходит быстро.

Но проблема в том, что когда я хочу использовать весь этот FIFO в качестве numpy.ndarray и выполнить некоторые математические вычисления (например, np.dot(signal,fifo)), я не могу найти способ получить соответствующий массив без операции O(n).
Это похоже на уже изобретенное колесо. Я искал в Интернете и что-то пробовал, но ничего из этого мне не подходит:
  • Код: Выделить всё

    input[1:] = input[:-1]; input[0] = new_val
    пока наивный, но наиболее эффективный способ, но все равно O(n)
  • collection.deque: хорошая производительность при постановке в очередь/удалении из очереди, но работа с другим массивом numpy занимает много времени (кажется, numpy сначала преобразует deque в numpy.ndarray, а затем выполняет математические вычисления, что займет много времени)
  • индексация: input[np.arange(start,start+size)%size] это расширенная индексация, поэтому она возвращает новый массив, а часть создания индексного массива делает ее еще медленнее
  • Код: Выделить всё

    np.r_[input[start:],input[:start]]
    , лучше, чем индексация, когда размер буфера большой, но все равно O(n)
  • Код: Выделить всё

    np.roll(input,-start)
    , O(n) и медленнее
  • Код: Выделить всё

    np.concatenate([input[start:],input[:start]])
    , O(n), медленнее, чем наивный способ, но быстрее, чем другие.
поскольку исходный массив непрерывен, поэтому я также попробовал использовать трюк с шагами/формой, чтобы создать представление исходного массива, но ничего не получилось.
Итак, я пришел сюда за помощью, или это должно быть O(n)?
Ответить

Быстрый ответ

Изменение регистра текста: 
Смайлики
:) :( :oops: :roll: :wink: :muza: :clever: :sorry: :angel: :read: *x)
Ещё смайлики…
   
К этому ответу прикреплено по крайней мере одно вложение.

Если вы не хотите добавлять вложения, оставьте поля пустыми.

Максимально разрешённый размер вложения: 15 МБ.

Вернуться в «Python»