[python] numpy 배열을 뒤집는 가장 효율적인 방법

현재 코드를 프로파일 링 한 후, numpy array reversion의 반복 작업은 실행 시간의 큰 덩어리를 믿었습니다. 내가 지금 가지고있는 것은 일반적인보기 기반 방법입니다.

reversed_arr = arr[::-1]

더 효율적으로 수행 할 수있는 다른 방법이 있습니까, 아니면 비현실적 인 numpy 성능에 대한 집착에서 온 환상입니까?



답변

만들 때 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 전문가는 아니지만 numpy에서 일을하는 가장 빠른 방법 인 것 같습니다. 이것이 당신이 이미하고있는 일이라면, 당신이 그것을 향상시킬 수 있다고 생각하지 않습니다.

추신 : numpy views에 대한 훌륭한 토론 :

numpy 배열을 보시겠습니까?


답변

위에서 언급했듯이 a[::-1]실제로보기 만 생성하므로 일정 시간 작업입니다 (배열이 커질수록 시간이 오래 걸리지 않습니다). 당신이 연속으로 배열을해야하는 경우 (예를 들어, 당신은 그것으로 많은 벡터 연산을 수행하고 있기 때문에) ascontiguousarray최대한 빨리 약 flipup/ fliplr:

여기에 이미지 설명을 입력하십시오


플롯을 생성하는 코드 :

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,
)


답변

이 답변은 아직 답변으로 표시되지 않은 것 같습니다 … Thomas Arildsen의 답변은 올바른 답변이어야합니다.

np.flipud(your_array) 

1d 배열 인 경우 (열 배열)

matrizes와 함께

fliplr(matrix)

flipud(matrix)을 뒤집고 열을 뒤집 으려는 경우. 1 차원 열 배열을 2 차원 행 배열 (하나의 없음 레이어가있는 행렬)로 만든 다음 뒤집을 필요가 없습니다.


답변

np.fliplr() 배열을 왼쪽에서 오른쪽으로 뒤집습니다.

1d 배열의 경우 약간 트릭해야합니다.

arr1d = np.array(some_sequence)
reversed_arr = np.fliplr([arr1d])[0]


답변

에 대한 이전 답변을 확장하겠습니다 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]


답변

다른 사람들이 말한 것을 확장하면 간단한 예를 들어 보겠습니다.

1D 어레이가있는 경우 …

>>> 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


답변

음수와 긴 목록으로 작업하려면 다음을 수행하십시오.

b = numpy.flipud(numpy.array(a.split(),float))

flipud는 1d arra를위한 곳