복붙노트

[PYTHON] 큰 Numpy 배열 작업을위한 기술?

PYTHON

큰 Numpy 배열 작업을위한 기술?

하나 이상의 Numpy 배열에서 많은 중간 연산을 수행해야하는 경우가 있습니다. 이로 인해 MemoryErrors가 신속하게 발생할 수 있습니다. 지금까지의 내 연구에서 U는 Pickling (Pickle, CPickle, Pytables 등)과 gc.collect ()가 이것을 완화하는 방법이라는 것을 알게되었습니다. 나는 프로그래머가 대량의 데이터를 다룰 때 경험이있는 다른 기술이 있는지 궁금해했다. (물론 전략 / 코드에서 중복을 제거하는 것 이외에).

또한 내가 확신 할 수있는 한 가지는 자유가 없다는 것입니다. 이러한 기술 중 일부는 절충점 (즉, 속도, 견고성 등)입니까?

해결법

  1. ==============================

    1.나는 너의 고통을 느낀다. 때때로 나중에 버릴 값에 배열의 크기의 몇 배를 저장하게된다. 한 번에 하나의 항목을 배열에서 처리 할 때 이것은 무의미하지만 벡터화 할 때 사용자를 죽일 수 있습니다.

    나는 너의 고통을 느낀다. 때때로 나중에 버릴 값에 배열의 크기의 몇 배를 저장하게된다. 한 번에 하나의 항목을 배열에서 처리 할 때 이것은 무의미하지만 벡터화 할 때 사용자를 죽일 수 있습니다.

    일러스트레이션을 위해 예제를 사용합니다. 최근 numpy를 사용하여 여기에 설명 된 알고리즘을 코딩했습니다. 이 알고리즘은 RGB 이미지를 사용하여 CMYK 이미지로 변환하는 컬러 맵 알고리즘입니다. 모든 픽셀에 대해 반복되는 프로세스는 다음과 같습니다.

    이 문제를 처리하기 위해 할 수있는 몇 가지 방법은 다음과 같습니다.

    단일 패스에서 1,000x1000 배열을 처리 할 수없는 경우 일 수 있습니다. 하지만 파이썬 for 루프로 100x1000의 배열을 반복 할 수 있다면 여전히 1,000,000 개가 넘는 파이썬 반복자를 훨씬 능가 할 것입니다! 그것은 느려질 것입니다, 그렇습니다, 그러나 많이는 아닙니다.

    위의 보간 예제와 직접적으로 관련이 있습니다. 각 차원에서 4 비트를 갖는 입체 큐브에서 보간하기 때문에 가능한 16x16x16 결과 만 16x16x16 바이트의 16 배열에 저장할 수 있습니다. 따라서 전 메모리에 64KB의 메모리를 사용하여 미리 계산하고 저장할 수 있으며 엄청난 메모리 비용으로 모든 픽셀에 대해 동일한 작업을 다시 수행하는 대신 전체 이미지에 대해 값을 하나씩 조회 할 수 있습니다. 64x64 픽셀만큼 작은 이미지는 이미 지불되며 기본적으로 배열을 세분 할 필요없이 x6 배의 픽셀로 이미지를 처리 ​​할 수 ​​있습니다.

    중간 값이 단일 uint8에 들어갈 수 있으면 int32 배열을 사용하지 마십시오! 이것은 침묵하는 오버 플로우로 인한 신비한 오류의 악몽으로 바뀔 수 있지만 조심하면 리소스를 크게 절약 할 수 있습니다.

  2. ==============================

    2.가장 중요한 속임수 : 몇 개의 큰 배열을 할당하고, 임시 배열을 많이 사용하고 폐기하는 대신에 일부를 사용하고 재활용합니다. 약간 구식이지만, 신중한 프로그래밍 속도로 인상적 일 수 있습니다. (정렬 및 데이터 지역성을보다 잘 제어 할 수 있으므로 숫자 코드를보다 효율적으로 만들 수 있습니다.)

    가장 중요한 속임수 : 몇 개의 큰 배열을 할당하고, 임시 배열을 많이 사용하고 폐기하는 대신에 일부를 사용하고 재활용합니다. 약간 구식이지만, 신중한 프로그래밍 속도로 인상적 일 수 있습니다. (정렬 및 데이터 지역성을보다 잘 제어 할 수 있으므로 숫자 코드를보다 효율적으로 만들 수 있습니다.)

    두 번째 : numpy.memmap을 사용하여 디스크에 대한 OS 캐싱이 충분히 효율적이기를 바랍니다.

    셋째 : @Jaime이 지적한 것처럼 전체 행렬이 커지면 un block sub-matrices를 처리하십시오.

    편집하다:

    SE에서이 대답에서 지적한 것처럼 불필요한 목록 이해를 피하십시오.

  3. ==============================

    3.dask.array 라이브러리는 차단 알고리즘을 사용하여 다중 코어가있는 메모리보다 큰 배열을 처리하는 numpy 인터페이스를 제공합니다.

    dask.array 라이브러리는 차단 알고리즘을 사용하여 다중 코어가있는 메모리보다 큰 배열을 처리하는 numpy 인터페이스를 제공합니다.

    당신은 또한 스파르타, 디스 트래, Biggus를 들여다 볼 수 있습니다.

  4. ==============================

    4.가능하면 numexpr을 사용하십시오. ** 2 + b ** 2 + 2 * a * b (a 및 b 배열의 경우)와 같은 숫자 계산의 경우

    가능하면 numexpr을 사용하십시오. ** 2 + b ** 2 + 2 * a * b (a 및 b 배열의 경우)와 같은 숫자 계산의 경우

    중형 및 대형 배열의 경우, 그다지 빠르지 않습니다.

    위에 주어진 웹 페이지를 살펴보면 numexpr이 당신에게 적합한 지 이해할 수있는 예제가 있습니다.

  5. from https://stackoverflow.com/questions/14351255/techniques-for-working-with-large-numpy-arrays by cc-by-sa and MIT license