3.3. 행렬#
행렬(array
)은 수학에서 나오는 행렬(matrix) 형태의 자료를 컴퓨터에 저장하기 위한 자료 형식이다.
이 과목에서는 행렬 형식보다 데이터프레임 형식의 자료를 주로 이용한다. 이 장에서는 라이브러리 numpy
에서 제공하는 행렬의 간단한 사용법만 살펴볼것이다.
행렬 형식은 라이브러리 numpy
를 불러서 사용할 수 있다. 다음은 numpy
라이브러리를 np
로 지칭하여 사용하겠다는 명령이다.
import numpy as np
행렬 형식의 자료는 차원(dimension)이 있다. 이 과목에서는 1차원 행렬과 2차원 행렬만 배워 볼 것이다.
일단 숫자 1,2,3,4,5,6 으로 구성된 1차원 행렬은 다음과 같이 정의한다. np
로 지정된 numpy
라이브러리에서 함수 array
를 사용한다. 괄호 ()
안에 숫자를 리스트로 묶어서 넣어주면 된다.
a = np.array([1,2,3,4,5,6])
a
array([1, 2, 3, 4, 5, 6])
행렬과 리스트(list)의 차이점은 행렬은 리스트와 달리 같은 형식의 자료만 모아 놓을 수 있다.
예를 들어 다음과 같이 문자와 숫자를 함께 저장하는 행렬은 정의가 안된다. 아래 명령을 실행시키면 숫자가 모두 문자열로 변환된 행렬이 생성되는 것을 알 수 있다.
np.array([1, 2, 'a'])
array(['1', '2', 'a'], dtype='<U21')
행렬의 원소는 다음과 같이 순서의 위치를 괄호 []
안에 넣어서 불러낼 수 있다. 위치의 순서가 0부터 시작하는 것에 유의하자.
a[0]
1
a[4]
5
a[6]
---------------------------------------------------------------------------
IndexError Traceback (most recent call last)
<ipython-input-6-84c1e027215d> in <module>
----> 1 a[6]
IndexError: index 6 is out of bounds for axis 0 with size 6
하나의 원소가 아닌 여러 개의 원소들은 리스트를 이용하여 다음과 같이 선택할 수 있다.
a[[0,1,2]]
array([1, 2, 3])
a[[0,3,5]]
array([1, 4, 6])
아래 코드에서 0:3
은 일정하게 감소하거나 증가하는 숫자들에 대한 형식이며 이를 범위(range
) 형식이라고 부른다. 이런 범위 형식는 문자열의 일부를 추출할 때 사용하였다.
start:end
0:3
은 0
으로 시작해서 3-1=2
로 끝나는 정수의 범위을 의미한다. 범위가 end
로 끝나지 않고 end-1
로 끝나는 것에 유의하자.
a[0:3]
array([1, 2, 3])
이제 numpy
에서 일정한 크기로 증가하거나 감소하는 수들로 이루어진 행렬을 한번에 만드는 함수 arange
를 사용해보자.
numpy
라이브러리의 함수 arange()
는 괄호 안에 3가지 인자(argument)를 넣어서 생성된 범위 형식에 따라서 행렬을 만들어 준다.
arange(start, stop, step)
start
: 시작하는 수stop
: 끝나는 수step
: 증가하는 수 (음수도 가능)
만약 첫 번째 인자만 있는 경우 0으로 시작해서 start-1
로 끝나는 정수의 행렬을 만들어 준다.
np.arange(6)
array([0, 1, 2, 3, 4, 5])
만약 첫 번째와 두 번째 인자만 있는 경우 start
으로 시작해서 end-1
로 끝나는 정수의 행렬을 만들어 준다.
np.arange(1,10)
array([1, 2, 3, 4, 5, 6, 7, 8, 9])
세 번째 인자는 증가하는 수를 지정한다.
np.arange(0, 10, 3)
array([0, 3, 6, 9])
함수 arange()
는 정수 뿐만 아니라 부동소숫점 형태의 행렬도 생성할 수 있다
np.arange(0, 1, 0.1)
array([0. , 0.1, 0.2, 0.3, 0.4, 0.5, 0.6, 0.7, 0.8, 0.9])
np.arange(10, -10, -2)
array([10, 8, 6, 4, 2, 0, -2, -4, -6, -8])
이제 2차원 행열을 만들어 보자. 다음과 같은 행이 2개이고 열이 4개인 2차원 행렬은 다음 코드로 만들 수 있다.
아래에서 reshape(r,c)
메소드는 1차원 행렬을 행의 수가 r
, 열의 수가 r
인 행렬로 만드는 기능을 한다.
b = np.arange(1,9).reshape(2, 4)
b
array([[1, 2, 3, 4],
[5, 6, 7, 8]])
위의 결과를 활용하면 동일한 2차원 행렬을 다음과 같이 만들 수 있다.
c = np.array( [ [1, 2, 3, 4], [5, 6, 7, 8] ])
c
array([[1, 2, 3, 4],
[5, 6, 7, 8]])
2차원 행렬의 원소는 1차원과 유사하게 일부를 지정하여 볼 수 있다.
b[0,0]
1
b[0,0:4]
array([1, 2, 3, 4])
b[0:2, 1:3]
array([[2, 3],
[6, 7]])
행렬 형식은 범위가 정의된 범위에서 벗어나도 오류가 나오지 않고 주어진 범위에 포함되는 부분만 슬라이싱해준다.
이러한 현상을 유용하게 이용할 수도 있겠지만 언제나 유효한 범위를 사용하는갓이 좋다.
b[1:3, 1:3]
array([[6, 7]])
행렬을 슬라이싱하는 경우 한 개의 행, 여러 개의 열을 선택하면 우리의 직관과 다르게 결과가 나오니 주의하자.
일단 규칙은 행의 수가 1 이거나 열의 수가 1이면 결과는 1차원 행렬이 된다.
c = b[0:2,1]
c
array([2, 6])
c.ndim
1
d = b[1, 0:3]
d
array([5, 6, 7])
d.ndim
1