코드로 보는 NumPy Tutorial

January 30, 2017

NumPy는 파이썬에서 계산을 위해서 사용하는 가장 유명한 라이브러리라고 해도 과언이 아닙니다(사실 이거 말고 아는게 없습니다). 그 중에서 행렬 연산에 관한 기능을 코드와 함께 정리해봤습니다.

생성하기

A = np.array([1.0, 2.0, 3.0])
#=> [1. 2. 3.]

type(A)
#=> <class 'numpy.ndarray'>

np.arange(10)
#=> array([0, 1, 2, 3, 4, 5, 6, 7, 8, 9])
np.arange(0, 10, 2)
#=> array([0, 2, 4, 6, 8])

np.ones((2, 3), dtype=int)
# array([[1, 1, 1],
#        [1, 1, 1]])

np.random.random((2, 3))
# array([[ 0.24595208,  0.27814662,  0.5671275 ],
#        [ 0.56680138,  0.97115287,  0.22724825]])

def f(x, y):
    return 10*x + y
A = np.fromfunction(f, (2, 4), dtype=int)
# array([[ 0,  1,  2,  3],
#        [10, 11, 12, 13]])

사양 확인

M = np.array([[1, 2], [3, 4]])
# array([[1, 2],
#        [3, 4]])
M.shape
#=> (2, 2)
M.dtype
#=> dtype('int64')

연산하기

elementwize

X = np.array([1.0, 2.0, 3.0])
Y = np.array([2.0, 4.0, 6.0])

X + Y
#=> array([ 3.,  6.,  9.])
X - Y
#=> array([-1., -2., -3.])
X * Y
#=> array([  2.,   8.,  18.]) 
X / Y
#=> array([ 0.5,  0.5,  0.5])
X * 2
#=> array([ 2.,  4.,  6.])

행렬곱

A = np.array([[1, 2], [3, 4]])
B = np.array([[1, 2], [2, 1]])
A.dot(B)
# array([[ 5,  4],
#        [11, 10]])
np.dot(A, B)
# array([[ 5,  4],
#        [11, 10]])

Universal Functions

A = np.random.random((2, 3))
# array([[ 0.06462051,  0.56454357,  0.80359124],
#        [ 0.21630644,  0.05226016,  0.52533345]])
A.sum()
#=> 2.5718191614547998
A.min()
#=> 0.1862602113776709
A.max()
#=> 0.6852195003967595

# axis로 축 방향을 지정할 수도 있음
A.sum(axis=0) # 각 열의 합
#=> array([ 0.28092695,  0.61680373,  1.32892469])
A.min(axis=1) # 각 행의 최소값
#=> array([ 0.06462051,  0.05226016])
aAcumsum(axis=1) # 각 행의 누적합
# array([[ 0.06462051,  0.62916408,  1.43275532],
#        [ 0.21630644,  0.2685666 ,  0.79390005]])

인덱스 연산

A = np.array([[1, 2], [3, 4]])
A[0]
#=> array([1, 2])
A[0][0]
#=> 1

A[np.array([0])]
#=> array([[1, 2]])
A > 1
# array([[False, True],
#        [ True, True]], dtype=bool)
A[A > 1]
#=> array([2, 3, 4])

dots 연산

A = np.array( [[[  0,  1,  2],
                [ 10, 12, 13]],
               [[100,101,102],
                [110,112,113]]])
A.shape
#=> (2, 2, 3)
A[1, ...]
# array([[100, 101, 102],
#        [110, 112, 113]])
A[1, :, :] # 동치
# array([[100, 101, 102],
#        [110, 112, 113]])
A[1] # 동치
# array([[100, 101, 102],
#        [110, 112, 113]])

A[..., 2]
# array([[  2,  13],
#        [102, 113]])
A[:, :, 2] # 동치
# array([[  2,  13],
#        [102, 113]])

...:로 나머지를 채움.

변환하기

A = np.arange(12)
#=> array([ 0,  1,  2,  3,  4,  5,  6,  7,  8,  9, 10, 11])
B = A.reshape(4, 3) #=> 변환된 행렬을 반환
# array([[ 0,  1,  2],
#        [ 3,  4,  5],
#        [ 6,  7,  8],
#        [ 9, 10, 11]])
A.resize((3, 4)) #=> 자체를 변환함(파괴적)
# array([[ 0,  1,  2,  3],
#        [ 4,  5,  6,  7],
#        [ 8,  9, 10, 11]])
A.flatten()
#=> array([ 0,  1,  2,  3,  4,  5,  6,  7,  8,  9, 10, 11])
A.ravel()
#=> array([ 0,  1,  2,  3,  4,  5,  6,  7,  8,  9, 10, 11])
A.T # 전치 행렬
# array([[ 0,  4,  8],
#        [ 1,  5,  9],
#        [ 2,  6, 10],
#        [ 3,  7, 11]])
A.shape = 2, 6 # 파괴적
# array([[ 0,  1,  2,  3,  4,  5],
#        [ 6,  7,  8,  9, 10, 11]])
A.reshape(3, -1) #=> 변환된 행렬을 반환
# array([[ 0,  1,  2,  3],
#        [ 4,  5,  6,  7],
#        [ 8,  9, 10, 11]])
A = np.array([[1, 2], [3, 4]])
# array([[1, 2],
#        [3, 4]])
B = np.array([[5, 6], [7, 8]])
# array([[5, 6],
#        [7, 8]])

np.vstack((A, B))
# array([[1, 2],
#        [3, 4],
#        [5, 6],
#        [7, 8]])

np.hstack((A, B))
# array([[1, 2, 5, 6],
#        [3, 4, 7, 8]])

A = np.array((1, 2, 3))
B = np.array((2, 3, 4))
np.column_stack((A, B))
# array([[1, 2],
#        [2, 3],
#        [3, 4]])
A = np.arange(24).reshape(2, 12)
# array([[ 0,  1,  2,  3,  4,  5,  6,  7,  8,  9, 10, 11],
#        [12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23]])

np.hsplit(A, 3) # 열 방향으로 3조각.
# [array([[ 0,  1,  2,  3],
#        [12, 13, 14, 15]]), array([[ 4,  5,  6,  7],
#        [16, 17, 18, 19]]), array([[ 8,  9, 10, 11],
#        [20, 21, 22, 23]])]
np.hsplit(A, (3, 4)) # 3번째 열을 기준으로 쪼갬
# [array([[ 0,  1,  2],
#        [12, 13, 14]]), array([[ 3],
#        [15]]), array([[ 4,  5,  6,  7,  8,  9, 10, 11],
#        [16, 17, 18, 19, 20, 21, 22, 23]])]

A = np.arange(12).reshape(2, 6)
# array([[ 0,  1,  2,  3,  4,  5],
#        [ 6,  7,  8,  9, 10, 11]])

C = A.view()
C is A
#=> False
C.base is A # 실 데이터는 A와 동일함
#=> True
C.flags.owndata
#=> False
C.shape = 3, 4
A.shape
#=> (2, 6)
C[0, 3] = 99 # A와 동일한 데이터를 보고 있으므로 A도 변경됨
A
# array([[ 0,  1,  2, 99,  4,  5],
#        [ 6,  7,  8,  9, 10, 11]])

Reference