numpy 배열과 행렬의 차이점은 무엇입니까? 어느 것을 사용해야합니까?


346

각각의 장단점은 무엇입니까?

내가 본 것 중 하나가 필요할 경우 둘 중 하나를 다른 것으로 대체 할 수 있으므로 둘 다 사용하지 않아도됩니까?

프로그램의 스타일이 나의 선택에 영향을 줍니까? 나는 numpy를 사용하여 기계 학습을하고 있으므로 실제로 많은 행렬이 있지만 많은 벡터 (배열)가 있습니다.


3
나는 대답을 정당화하기에 충분한 정보가 없지만 주요 차이점을 알 수있는 것은 곱셈의 구현입니다. 행렬은 행렬 / 텐서 곱셈을 수행하는 반면 배열은 요소 별 곱셈을 수행합니다.
Mike Axiak

5
Python 3.5는 행렬 곱셈 (PEP 465)을위한 infix @ 연산자를 추가했으며 NumPy 1.10은이를 지원합니다. 따라서 Python 3.5 이상 및 NumPy 1.10 이상을 사용하는 경우 , where 및 are 2D A @ B대신 쓸 수 있습니다 . 이것은 일반 IMHO 대신에 사용하는 주요 이점을 제거합니다 . A.dot(B)ABndarraymatrixndarray
MiniQuark

답변:



396

Numpy 행렬 은 엄격하게 2 차원이며 Numpy 배열 (ndarray)은 N 차원입니다. 행렬 객체는 ndarray의 하위 클래스이므로 ndarray의 모든 속성과 메소드를 상속합니다.

numpy 행렬의 주요 장점은 행렬 곱셈에 편리한 표기법을 제공한다는 것입니다. a와 b가 행렬이면 a*b행렬 곱입니다.

import numpy as np

a = np.mat('4 3; 2 1')
b = np.mat('1 2; 3 4')
print(a)
# [[4 3]
#  [2 1]]
print(b)
# [[1 2]
#  [3 4]]
print(a*b)
# [[13 20]
#  [ 5  8]]

반면에, Python 3.5부터 NumPy는 @연산자를 사용하여 infix 행렬 곱셈을 지원 하므로 Python> = 3.5에서 ndarray를 사용하여 행렬 곱셈과 동일한 편의를 얻을 수 있습니다.

import numpy as np

a = np.array([[4, 3], [2, 1]])
b = np.array([[1, 2], [3, 4]])
print(a@b)
# [[13 20]
#  [ 5  8]]

행렬 객체와 ndarray는 모두 .T전치 (transpose)를 반환해야하지만 행렬 객체는 .H켤레 전치 (conjugate transpose)와 .I역수 (inverse)에도 있습니다.

반대로 numpy 배열은 작업이 요소별로 적용된다는 규칙을 일관되게 준수합니다 (새 @연산자 제외 ). 경우에 따라서, a그리고 bNumPy와 배열은 다음 a*b요소 와이즈 성분을 곱하여 이루어지는 배열이다 :

c = np.array([[4, 3], [2, 1]])
d = np.array([[1, 2], [3, 4]])
print(c*d)
# [[4 6]
#  [6 4]]

행렬 곱셈의 결과를 얻으려면 다음을 사용하십시오 np.dot(또는 @위에 표시된 것처럼 Python> = 3.5).

print(np.dot(c,d))
# [[13 20]
#  [ 5  8]]

**운영자는 다르게 동작합니다 :

print(a**2)
# [[22 15]
#  [10  7]]
print(c**2)
# [[16  9]
#  [ 4  1]]

a행렬 이므로 a**2행렬 product를 반환합니다 a*a. cndarray 이므로 c**2각 구성 요소를 요소 단위로 제곱 한 ndarray를 반환합니다.

행렬 객체와 ndarrays ( np.ravel항목 선택 및 시퀀스 동작과 관련 이 있음)에는 다른 기술적 차이가 있습니다.

numpy 배열의 주요 장점은 2 차원 행렬보다 더 일반적이라는 것 입니다. 3 차원 배열을 원하면 어떻게됩니까? 그런 다음 행렬 객체가 아닌 ndarray를 사용해야합니다. 따라서 매트릭스 객체 사용을 배우는 것이 더 많은 작업입니다. 매트릭스 객체 작업과 ndarray 연산을 배워야합니다.

행렬과 배열을 혼합하는 프로그램을 작성하면 변수가 어떤 유형의 객체인지 추적해야하기 때문에 곱셈이 예상치 못한 것을 반환하지 않기 때문에 삶을 어렵게 만듭니다.

반대로, ndarray 만 사용하면 약간 다른 기능 / 표기법을 제외하고 매트릭스 객체가 수행 할 수있는 모든 작업을 수행 할 수 있습니다.

NumPy 매트릭스 제품 표기법 (Python> = 3.5의 ndarray로 거의 우아하게 달성 할 수 있음)의 시각적 매력을 기꺼이 포기하고 싶다면 NumPy 배열이 확실히 갈 길이라고 생각합니다.

추신. 물론, 당신은 정말 있기 때문에, 다른의 비용으로 하나를 선택할 필요가 없습니다 np.asmatrixnp.asarray(배열은 2 차원입니다만큼) 당신이 다른 하나를 변환 할 수 있습니다.


NumPy와의 차이점의 개요가 arraysNumPy와의 대 matrixES 여기가 .


7
궁금한 mat**nreduce(np.dot, [arr]*n)
점이 있으시면

6
아니면 그냥np.linalg.matrix_power(mat, n)
에릭

매트릭스가 더 빠를 지 궁금합니다 ... ndarray보다 검사를 덜 수행해야한다고 생각할 것입니다.
PascalVKooten

1
실제로 timeit 테스트는과 같은 ndarray 작업 np.dot(array2, array2)이 더 빠름을 보여줍니다 matrix1*matrix2. 이것은 matrixndarray의 하위 클래스 이기 때문에 의미 가 있습니다 __mul__. matrix.__mul__전화np.dot . 여기 코드 재사용이 있습니다. 더 적은 수의 검사를 수행하는 대신 matrix*matrix추가 함수 호출이 필요합니다. 따라서 사용의 이점은 matrix성능이 아니라 순전히 구문입니다.
unutbu

4 * 1 + 3 * 3 np.dot (c, d)를했을 때 13이됩니다. 이것은 실제로 수학에서 교차 곱이라고 불립니다
PirateApp

92

Scipy.org는 다음과 같은 배열 사용을 권장합니다.

* '배열'또는 '행렬'? 어느 것을 사용해야합니까? - 짧은 답변

배열을 사용하십시오.

  • 그것들은 numpy의 표준 벡터 / 행렬 / 텐서 타입입니다. 많은 numpy 함수는 행렬이 아닌 배열을 반환합니다.

  • 요소 별 연산과 선형 대수 연산에는 분명한 차이가 있습니다.

  • 원하는 경우 표준 벡터 또는 행 / 열 벡터를 가질 수 있습니다.

배열 유형을 사용하는 유일한 단점은 두 개의 텐서를 곱하는 (스칼라 곱, 행렬 벡터 곱하기 등) dot대신 사용해야한다는 것입니다 *.


11
허용 된 답변이 더 많은 정보를 제공하지만 실제 답변은 실제로 고수합니다 ndarray. 사용에 대한 주요 주장은 matrix코드가 선형 대수학에서 무겁고 dot함수를 호출 할 때 덜 명확하게 보일 것 입니다. 그러나 @-연산자를 행렬 곱셈과 함께 사용할 수있게되었으므로이 주장은 앞으로 사라질 것입니다 ( PEP 465 참조) . 여기에는 Python 3.5와 최신 버전의 Numpy가 필요합니다. 매트릭스 클래스는 앞으로 더 이상 사용되지 않을 수 있으므로 새 코드에 ndarray를 사용하는 것이 좋습니다.
Bas Swinckels

6
이 페이지는 scipy.sparse행렬 에 대해 은혜롭게 잊어 버립니다 . 코드에서 밀도가 높고 희소 행렬을 모두 사용하는 경우를 사용하는 것이 훨씬 쉽습니다 matrix.
David Nemeskey

3
필자의 의견으로는 배열의 주요 단점은 열 슬라이싱이 혼란스럽고 수학적으로 실제로 소리가 들리지 않는 평면 배열을 반환한다는 것입니다. 또한 numpy 배열은 scipy.sparse 행렬과 같은 방식으로 처리 할 수 ​​없지만 numpy 행렬은 기본적으로 희소 행렬과 자유롭게 교환 할 수 있다는 중요한 단점이 있습니다. 이 맥락에서 scipy는 배열 사용을 권장하고 호환되는 희소 배열을 제공하지 않습니다.
라디오 제어

29

unutbu의 목록에 하나의 사례를 추가하기 만하면됩니다.

numpy 행렬 또는 matlab과 같은 행렬 언어와 비교할 때 numpy ndarrays의 가장 큰 실제 차이점 중 하나는 치수가 축소 작업에서 유지되지 않는다는 것입니다. 행렬의 크기는 항상 2d이지만 배열의 평균은 1 차원보다 작습니다.

예를 들어 행렬 또는 배열의 demean 행 :

매트릭스

>>> m = np.mat([[1,2],[2,3]])
>>> m
matrix([[1, 2],
        [2, 3]])
>>> mm = m.mean(1)
>>> mm
matrix([[ 1.5],
        [ 2.5]])
>>> mm.shape
(2, 1)
>>> m - mm
matrix([[-0.5,  0.5],
        [-0.5,  0.5]])

배열로

>>> a = np.array([[1,2],[2,3]])
>>> a
array([[1, 2],
       [2, 3]])
>>> am = a.mean(1)
>>> am.shape
(2,)
>>> am
array([ 1.5,  2.5])
>>> a - am #wrong
array([[-0.5, -0.5],
       [ 0.5,  0.5]])
>>> a - am[:, np.newaxis]  #right
array([[-0.5,  0.5],
       [-0.5,  0.5]])

또한 배열과 행렬을 혼합하면 많은 "행복한"디버깅 시간이 발생한다고 생각합니다. 그러나 scipy.sparse 행렬은 곱셈과 같은 연산자의 관점에서 항상 행렬입니다.


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