Самый эффективный способ обратного преобразования массива numpy
Верьте этому или нет, после профилирования моего текущего кода повторяющаяся операция восстановления numpy-массива съела гигантский кусок времени выполнения. Сейчас у меня есть общий метод, основанный на представлении:
reversed_arr = arr[::-1]
Есть ли какой-либо другой способ сделать это более эффективно, или это просто иллюзия моей одержимости нереалистичной производительностью в несколько раз?
Ответы
Ответ 1
При создании reversed_arr
вы создаете представление в исходном массиве. Затем вы можете изменить исходный массив, и представление будет обновляться, чтобы отразить изменения.
Вы повторно создаете представление чаще, чем вам нужно? Вы должны сделать что-то вроде этого:
arr = np.array(some_sequence)
reversed_arr = arr[::-1]
do_something(arr)
look_at(reversed_arr)
do_something_else(arr)
look_at(reversed_arr)
Я не эксперт по количеству, но похоже, что это был бы самый быстрый способ сделать что-то в numpy. Если это то, что вы уже делаете, я не думаю, что вы можете улучшить его.
P.S. Отличное обсуждение видов numpy здесь:
Просмотр в массив numpy?
Ответ 2
Как упомянуто выше, a[::-1]
действительно только создает представление, поэтому это операция с постоянным временем (и, как таковая, не занимает больше времени при увеличении массива). Если вам нужно, чтобы массив был смежным (например, потому что вы выполняете много векторных операций с ним), ascontiguousarray
примерно так же быстро, как flipup
/fliplr
:
![enter image description here]()
Код для генерации сюжета:
import numpy
import perfplot
perfplot.show(
setup=lambda n: numpy.random.randint(0, 1000, n),
kernels=[
lambda a: a[::-1],
lambda a: numpy.ascontiguousarray(a[::-1]),
lambda a: numpy.fliplr([a])[0],
],
labels=["a[::-1]", "ascontiguousarray(a[::-1])", "fliplr"],
n_range=[2 ** k for k in range(25)],
xlabel="len(a)",
logx=True,
logy=True,
)
Ответ 3
np.fliplr()
переворачивает массив слева направо.
Обратите внимание, что для 1d массивов вам нужно немного обмануть его:
arr1d = np.array(some_sequence)
reversed_arr = np.fliplr([arr1d])[0]
Ответ 4
Потому что это, кажется, не помечено как ответ еще... Ответ Томаса Арильдсена должен быть правильным: просто используйте
np.flipud(your_array)
если это 1-й массив (массив столбцов).
С матрицами do
fliplr(matrix)
если вы хотите изменить строки и flipud(matrix)
, если хотите перевернуть столбцы. Нет необходимости в создании массива 1d массива 2-мерного массива строк (матрица с одним слоем None), а затем перелистывания.
Ответ 5
Я расскажу о более раннем ответе о np.fliplr()
. Вот какой код, который демонстрирует построение 1d-массива, преобразование его в массив 2d, перевертывание его, а затем преобразование в 1d-массив. time.clock()
будет использоваться для поддержания времени, которое представлено в секундах.
import time
import numpy as np
start = time.clock()
x = np.array(range(3))
#transform to 2d
x = np.atleast_2d(x)
#flip array
x = np.fliplr(x)
#take first (and only) element
x = x[0]
#print x
end = time.clock()
print end-start
С сообщением о печати без комментариев:
[2 1 0]
0.00203907123594
С выражением о печати закомментировано:
5.59799927506e-05
Итак, с точки зрения эффективности, я считаю, что порядочный. Для тех из вас, кто любит делать это в одной строке, вот эта форма.
np.fliplr(np.atleast_2d(np.array(range(3))))[0]
Ответ 6
Подробно о том, что сказали другие, приведу короткий пример.
Если у вас есть одномерный массив...
>>> import numpy as np
>>> x = np.arange(4) # array([0, 1, 2, 3])
>>> x[::-1] # returns a view
Out[1]:
array([3, 2, 1, 0])
Но если вы работаете с 2D-массивом...
>>> x = np.arange(10).reshape(2, 5)
>>> x
Out[2]:
array([[0, 1, 2, 3, 4],
[5, 6, 7, 8, 9]])
>>> x[::-1] # returns a view:
Out[3]: array([[5, 6, 7, 8, 9],
[0, 1, 2, 3, 4]])
Это на самом деле не переворачивает Матрицу.
Следует использовать np.flip для реверсирования элементов
>>> np.flip(x)
Out[4]: array([[9, 8, 7, 6, 5],
[4, 3, 2, 1, 0]])
Если вы хотите распечатать элементы матрицы по одному, используйте плоскую и флип
>>> for el in np.flip(x).flat:
>>> print(el, end = ' ')
9 8 7 6 5 4 3 2 1 0
Ответ 7
Чтобы работать с отрицательными числами и длинным списком, вы можете сделать следующее:
b = numpy.flipud(numpy.array(a.split(),float))
Где flipud для 1d arra