일반 Python 목록에 비해 NumPy의 장점은 무엇입니까?


466

일반 Python 목록에 비해 NumPy 의 장점은 무엇입니까 ?

저는 약 100 개의 금융 시장 시리즈를 보유하고 있으며 100x100x100 = 1 백만 셀의 큐브 배열을 만들려고합니다. 표준 오류로 배열을 채우기 위해 각 y 및 z를 사용하여 각 x를 회귀 (3 변수) 할 것입니다.

"큰 행렬"의 경우 성능 및 확장 성 이유로 Python 목록과 달리 NumPy를 사용해야한다고 들었습니다. 나는 파이썬 목록을 알고 있으며 그들은 나를 위해 일하는 것 같습니다.

NumPy로 이사하면 어떤 혜택이 있습니까?

1000 시리즈 (즉, 큐브에 10 억 개의 부동 소수점 셀)가있는 경우 어떻게합니까?

답변:


727

NumPy의 배열은 Python 목록보다 작습니다 .Python에서 설명하는 목록의 목록은 최소 20MB 정도 소요되며 셀에 단 정밀도 부동 소수점이있는 NumPy 3D 배열은 4MB에 맞습니다. NumPy를 사용하면 항목 읽기 및 쓰기가 더욱 빨라집니다.

아마도 백만 개의 셀에는 그다지 신경 쓰지 않을 것이지만 분명히 10 억 셀에 대한 것입니다. 접근 방식은 32 비트 아키텍처에 적합하지 않지만 64 비트 빌드에서는 NumPy가 4GB 정도 떨어져 나갈 것입니다 , 파이썬만으로도 약 12GB (많은 크기의 포인터)-훨씬 더 비싼 하드웨어가 필요합니다!

차이점은 대부분 "간접 성"때문입니다. Python 목록은 Python 객체에 대한 포인터 배열입니다. 포인터 당 4 바이트 이상, 심지어 가장 작은 Python 객체 인 경우 16 바이트 (타입 포인터의 경우 4, 참조 횟수의 경우 4, 4 메모리 할당자는 16으로 반올림합니다. NumPy 배열은 균일 한 값의 배열입니다. 단 정밀도 숫자는 각각 4 바이트, 배정 밀도 숫자, 8 바이트를 사용합니다. 유연성은 떨어지지 만 표준 파이썬 목록의 유연성에 대해서는 대가를 지불해야합니다!


"sys.getsizeof ()"를 사용하여 동일한 수의 요소로 Python 목록과 NumPy 배열의 크기를 비교하려고 시도했지만 NumPy 배열이 훨씬 작다는 것을 나타내는 것은 아닙니다. 이 경우입니까 아니면 sys.getsizeof ()가 NumPy 배열의 크기를 알아내는 데 문제가 있습니까?
잭 심슨

3
@JackSimpson getsizeof은 신뢰할 수 없습니다. 설명서에는 다음과 같이 명시되어 있습니다. 객체에 직접 기여한 메모리 소비 만 설명하며, 객체의 메모리 소비는 설명하지 않습니다. 즉, 파이썬 목록을 중첩하면 요소의 크기가 고려되지 않습니다.
Bakuriu

4
getsizeof목록의 목록은 목록 객체 자체가 소비하는 RAM의 양과 데이터 배열의 포인터가 소비 한 RAM 만 알려주고 해당 포인터가 참조하는 객체가 얼마나 많은 RAM을 소비하는지는 알려주지 않습니다.
PM 2Ring

@AlexMartelli,이 번호를 어디서 구할 수 있는지 알려주십시오.
lmiguelvargasf

파이썬 목록 목록의 크기에 대한 추정치가 꺼져 있습니다. C float(4 바이트)의 4GB numpy 배열은 12GB가 아닌 32GB 상당의 lists 및 Python float(실제로는 Cs )에 가까운 것으로 변환됩니다 double. float64 비트 Python에서 각각 ~ 24 바이트 (할당 자에서 정렬 손실이 없다고 가정)와 list참조를 보유하기 위해 또 다른 8 바이트를 차지합니다 (그리고 그 list자체에 대한 초과 할당 및 객체 헤더를 무시합니다 . 정확히 얼마나 많은 할당이 발생했는지).
ShadowRanger

232

NumPy는 더 효율적이지 않습니다. 더 편리합니다. 많은 벡터 및 행렬 연산이 무료로 제공되므로 불필요한 작업을 피할 수 있습니다. 그리고 그들은 또한 효율적으로 구현됩니다.

예를 들어, 파일에서 직접 큐브로 큐브를 읽을 수 있습니다.

x = numpy.fromfile(file=open("data"), dtype=float).reshape((100, 100, 100))

두 번째 차원을 따라 합산 :

s = x.sum(axis=1)

임계 값을 초과하는 셀 찾기 :

(x > 0.5).nonzero()

3 차원을 따라 짝수 색인 된 슬라이스를 모두 제거하십시오.

x[:, :, ::2]

또한 많은 유용한 라이브러리가 NumPy 배열과 작동합니다. 통계 분석 및 시각화 라이브러리를 예로들 수 있습니다.

성능 문제가 없더라도 NumPy를 배우는 것은 노력할 가치가 있습니다.


감사합니다-세 번째 예제에서 또 다른 이유를 제시했습니다. 실제로 임계 값보다 높은 셀에 대한 행렬을 검색 할 것입니다. 또한 sqlLite에서로드하고있었습니다. 파일 접근 방식이 훨씬 더 효율적입니다.
Thomas Browne 2016 년

112

Alex는 메모리 효율성을 언급했으며 Roberto는 편의성을 언급했으며 이것들은 모두 장점입니다. 더 많은 아이디어를 위해 속도기능에 대해 언급하겠습니다. .

기능 : NumPy, FFT, 컨볼 루션, 빠른 검색, 기본 통계, 선형 대수학, 히스토그램 등이 많이 내장되어 있습니다. 실제로 FFT없이 살 수있는 사람은 누구입니까?

속도 : 다음은 목록과 NumPy 배열에 대한 합계를 수행하는 테스트입니다. NumPy 배열의 합계가 10 배 빠릅니다 (이 테스트에서는 마일리지가 다를 수 있음).

from numpy import arange
from timeit import Timer

Nelements = 10000
Ntimeits = 10000

x = arange(Nelements)
y = range(Nelements)

t_numpy = Timer("x.sum()", "from __main__ import x")
t_list = Timer("sum(y)", "from __main__ import y")
print("numpy: %.3e" % (t_numpy.timeit(Ntimeits)/Ntimeits,))
print("list:  %.3e" % (t_list.timeit(Ntimeits)/Ntimeits,))

내 시스템에서 (백업을 실행하는 동안) 다음을 제공합니다.

numpy: 3.004e-05
list:  5.363e-04

44

다음은 scipy.org 웹 사이트 의 FAQ에서 좋은 답변입니다 .

NumPy 배열은 (중첩 된) 파이썬 목록보다 어떤 장점을 제공합니까?

파이썬의 목록은 효율적인 범용 컨테이너입니다. 그것들은 (공정하게) 효율적인 삽입, 삭제, 추가 및 연결을 지원하며 Python의 목록 이해는 구성 및 조작을 쉽게합니다. 그러나 요소 제한과 곱셈과 같은 "벡터화"연산을 지원하지 않으며, 유형이 다른 객체를 포함 할 수 있다는 사실은 파이썬이 모든 요소에 대한 유형 정보를 저장하고 유형 디스패치 코드를 실행해야한다는 것을 의미합니다. 각 요소에서 작동 할 때. 이는 효율적인 C 루프로 수행 할 수있는 목록 작업이 거의 없음을 의미합니다. 각 반복에는 유형 확인 및 기타 Python API 부기가 필요합니다.


9

모두 numpy array와 python list의 거의 모든 주요 차이점을 강조했습니다. 단지 간단히 설명하겠습니다.

  1. Numpy 배열은 파이썬 목록 (동적으로 성장 할 수 있음)과 달리 생성시 고정 크기를 갖습니다. ndarray의 크기를 변경하면 새 배열이 생성되고 원본이 삭제됩니다.

  2. Numpy 배열의 요소는 모두 동일한 데이터 유형이어야합니다 (이종 유형도 가능하지만 수학적 연산을 허용하지는 않습니다). 따라서 메모리에서 동일한 크기가됩니다.

  3. Numpy arrays는 많은 수의 데이터에 대해 수학 및 기타 유형의 연산을 향상시킵니다. 일반적으로 이러한 작업은 시퀀스에서 파이썬 빌드를 사용하는 것보다 더 효율적이고 적은 코드로 실행됩니다.

당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.