문제

모든 것이 벡터화 된 것처럼 보이지만 다음 코드는 너무 느리게 실행됩니다.

from numpy import *
from scipy.sparse import *

n = 100000;
i = xrange(n); j = xrange(n);
data = ones(n);

A=csr_matrix((data,(i,j)));

x = A[i,j]

문제는 인덱싱 작업이 Python 함수로 구현되고 호출되는 것 같습니다. A[i,j] 다음 프로파일 링 출력이 발생합니다

         500033 function calls in 8.718 CPU seconds

   Ordered by: internal time

   ncalls  tottime  percall  cumtime  percall filename:lineno(function)
   100000    7.933    0.000    8.156    0.000 csr.py:265(_get_single_element)
        1    0.271    0.271    8.705    8.705 csr.py:177(__getitem__)
(...)

즉, 파이썬 기능 _get_single_element 100000 번이라고 불리는 것은 실제로 비효율적입니다. 왜 이것이 순수한 C로 구현되지 않습니까? 이 제한을 해결하고 위의 코드 속도를 높이는 방법을 아는 사람이 있습니까? 다른 스파스 매트릭스 유형을 사용해야합니까?

도움이 되었습니까?

해결책

당신이 사용할 수있는 A.diagonal() 대각선을 훨씬 더 빨리 검색하려면 (내 컴퓨터에서 0.0009 초 대 3.8 초). 그러나 임의의 인덱싱을 수행하려면 인덱스 목록만큼 슬라이스를 사용하지 않기 때문에 더 복잡한 질문입니다. _get_single_element 함수는 당신이 그것을 전달한 반복자 (i 및 j)를 통해 반복하기 때문에 100000 번 호출됩니다. 슬라이스는 [30 : 60,10] 또는 그와 비슷한 것입니다.

또한 나는 사용할 것입니다 csr_matrix(eye(n,n)) 단순화를 위해 반복자로 만든 것과 동일한 매트릭스를 만듭니다.

업데이트:

좋아, 당신의 질문은 진정으로 많은 임의의 요소에 빨리 액세스 할 수 있다는 것이므로 가능한 한 최선을 다해 질문에 답할 것입니다.

  • 왜 이것이 순수한 C로 구현되지 않습니까?

대답은 간단합니다. 아무도 그것에 도착하지 않았습니다. Scipy의 희소 매트릭스 모듈 영역에서 내가 본 것에 대해 여전히 많은 작업이 있습니다. C로 구현 된 부분 중 하나는 다른 스파 스 유교 형식 간의 변환입니다.

  • 이 제한을 해결하고 위의 코드 속도를 높이는 방법을 아는 사람이 있습니까?

실제로 드문 매트릭스 모듈에 뛰어 들어 속도를 높이려고 시도 할 수 있습니다. 나는 CSR 행렬을 사용하여 임의의 액세스를 위해 위의 코드를 시도 할 때 원본의 3 분의 1 미만으로 시간을 줄일 수있었습니다. _get_single_element _get_single_element에 직접 액세스하고 바운드 검사를 포함하여 코드를 크게 파악해야했습니다.

그러나 LIL_MATRIX를 사용하는 것이 더 빨랐지 만 (매트릭스를 초기화하는 데 느리게) LIL 행렬은 수행중인 인덱싱 유형에 대한 설정이 아니기 때문에 목록 이해력으로 액세스를 수행해야했습니다. CSR_MATRIX에 대한 목록 이해력을 사용하면 여전히 LIL 매트릭스 메소드가 앞서 나옵니다. 궁극적으로 LIL 매트릭스는 압축되지 않기 때문에 임의의 요소에 액세스하는 데 더 빠릅니다.

원래 양식으로 lil_matrix를 사용하면 위에 나열된 코드의 시간의 약 5 분의 1이 실행됩니다. 바운드 검사를 꺼내서 lil_matrix의 _get1 () 메소드를 직접 호출하면 원래 시간의 약 7%를 더 낮출 수 있습니다. 명확성을 위해 그것은 3.4-3.8 초에서 약 0.261 초로 속도를 높입니다.

마지막으로 LIL 매트릭스의 데이터에 직접 액세스하고 반복 된 기능 호출을 피하는 내 기능을 만들려고했습니다. 이것의 시간은 약 0.136 초였습니다. 이것은 또 다른 잠재적 최적화 인 데이터를 분류하는 것을 이용하지 못했습니다 (특히 동일한 행에있는 많은 요소에 액세스하는 경우).

당신이 그것보다 더 빨리 원한다면 당신은 당신의 자신의 C 코드 스파 스 스파스 매트릭스 구현을 작성해야 할 것입니다.

  • 다른 스파스 매트릭스 유형을 사용해야합니까?

글쎄, 나는 당신의 의도가 많은 요소에 액세스하려는 경우 lil 매트릭스를 제안하지만, 그것은 당신이해야 할 일에 달려 있습니다. 예를 들어 매트릭스를 곱해야합니까? 행렬 사이를 변경하면 적어도 (특정 상황에서) 매우 빠를 수 있으므로 다른 작업을 수행하기 위해 다른 행렬 형식으로 변경하지 마십시오.

매트릭스에서 실제로 대수 작업을 수행 할 필요가 없다면 기본적으로 사용하거나 유사한 것을 사용해야 할 수도 있습니다. DefaultDicts의 위험은 요소를 요구할 때마다 DITT에 있지 않을 때마다 해당 항목을 기본값으로 설정하고 문제가 될 수 있다는 것입니다.

다른 팁

_get_single_element는 'Object'의 기본 dtype가 사용될 때만 호출된다고 생각합니다. 다음과 같은 DTYPE를 제공해 보셨습니까? csr_matrix((data, (i,j)), dtype=int32)

라이센스 : CC-BY-SA ~와 함께 속성
제휴하지 않습니다 StackOverflow
scroll top