Numpy 정렬, 행렬 연산

CharliePark·2020년 8월 24일
0

TIL

목록 보기
10/67

권철민 선생님의 <파이썬 머신러닝 완벽 가이드> 책과 강의를 통해 공부하며 정리한 내용입니다.
/ 강의

(파이썬 머신러닝 완벽 가이드 Chap 01.03)

 

행렬의 정렬 - sort()와 argsort()

 

행렬 정렬

np.sort() 와 같이 넘파이에서 sort() 를 호출하는 방식과 ndarray.sort() 와 같이 행렬 자체에서 sort() 를 호출하는 방식이 있다.

np.sort() 의 경우 원 행렬은 유지하고 정렬된 행렬을 반환한다.

ndarray.sort() 의 경우 원 행렬 자체를 정렬한 형태로 변환하고, 반환값은 None 이다.

org_array = np.array([3, 1, 9, 5])
print('원본 행렬:', org_array)

# np.sort()로 정렬
sort_array1 = np.sort(org_array)
print('np.sort() 호출 후 반환된 정렬 행렬 :', sort_array1)
print('np.sort() 호출 후 원본 행렬 :', org_array)

# ndarray.sort()로 정렬
sort_array2 = org_array.sort()
print('np.sort() 호출 후 반환된 정렬 행렬 :', sort_array2)
print('np.sort() 호출 후 원본 행렬 :', org_array)

output

원본 행렬: [3 1 9 5]
np.sort() 호출 후 반환된 정렬 행렬 : [1 3 5 9]
np.sort() 호출 후 원본 행렬 : [3 1 9 5]
np.sort() 호출 후 반환된 정렬 행렬 : None
np.sort() 호출 후 원본 행렬 : [1 3 5 9]

 

내림차순으로 정렬하기 위해서는 [::-1]을 적용하면 된다

sort_array1_desc = np.sort(org_array)[::-1]
print('내림차순으로 정렬:', sort_array1_desc)

output

내림차순으로 정렬: [9 5 3 1]

 

행렬이 2차원 이상인 경우에 axis 축 값 설정을 통해 방향을 지정해줄 수 있다.

array2d = np.array([[8, 12], 
                   [7, 1 ]])
print('원본 행렬:\n', array2d)

sort_array2d_axis0 = np.sort(array2d, axis=0)
print('로우 방향으로 정렬:\n', sort_array2d_axis0)

sort_array2d_axis1 = np.sort(array2d, axis=1)
print('컬럼 방향으로 정렬:\n', sort_array2d_axis1)

output

원본 행렬:
 [[ 8 12]
 [ 7  1]]
로우 방향으로 정렬:
 [[ 7  1]
 [ 8 12]]
컬럼 방향으로 정렬:
 [[ 8 12]
 [ 1  7]]

 

정렬된 행렬의 인덱스를 반환하기

원본 행렬이 정렬되었을 때 원본 행렬의 원소에 대한 인덱스가 필요하다면, np.argsort() 를 이용하면 된다.

np.argsort() 는 원본 행렬 인덱스를 ndarray 형으로 반환한다

org_array = np.array([ 3, 1, 9, 5]) 
print(np.sort(org_array))

sort_indices = np.argsort(org_array)
print(type(sort_indices))
print('행렬 정렬 시 원본 행렬의 인덱스:', sort_indices)

output

[1 3 5 9]
<class 'numpy.ndarray'>
행렬 정렬 시 원본 행렬의 인덱스: [1 0 3 2]

 

마찬가지로 내림차순으로 정렬시 [::-1]을 적용하면 된다.

org_array = np.array([ 3, 1, 9, 5]) 
print(np.sort(org_array)[::-1])

sort_indices_desc = np.argsort(org_array)[::-1]
print('행렬 내림차순 정렬 시 원본 행렬의 인덱스:', sort_indices_desc)

output

[9 5 3 1]
행렬 내림차순 정렬 시 원본 행렬의 인덱스: [2 3 0 1]

 


NumPy의 ndarray는 RDBMS의 TABLE 칼럼이나, Pandas DataFrame 칼럼과 같은 메타 데이터를 가질 수 없다. 따라서, 실제 값과 그 값이 뜻하는 메타 데이터를 별도의 ndarray로 가져야만 한다.

ex) 학생별 시험 성적을 데이터로 표현한다고 하자.

'학생 이름'과 '시험 성적'을 각각 ndarray로 가져야 한다.

시험 성적순으로 학생 이름을 출력하고자 한다면, argsort() 를 이용해 반환된 인덱스를 팬시 인덱스로 적용하면 추출이 가능하다.

name_array=np.array(['John', 'Mike', 'Sarah', 'Kate', 'Samuel'])
score_array=np.array([78, 95, 84, 98, 88])

# score_array의 정렬된 값에 해당하는 원본 행렬 위치 인덱스 반환하고 이를 이용하여 name_array에서 name값 추출.  
sort_indices = np.argsort(score_array)
print("sort indices:", sort_indices)

name_array_sort = name_array[sort_indices]

score_array_sort = score_array[sort_indices]
print(name_array_sort)
print(score_array_sort)

output

sort indices: [0 2 4 1 3]
['John' 'Sarah' 'Samuel' 'Mike' 'Kate']
[78 84 88 95 98]

 


선형대수 연산 - 행렬 내적과 전치 행렬 구하기

행렬 내적(행렬 곱)

np.dot() 을 이용해 두 행렬의 내적이 가능하다.

행렬의 내적은 왼쪽 행렬의 열 개수와 오른쪽 행렬의 행 개수가 동일할 때만 가능하다.

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

dot_product = np.dot(A, B)
print('행렬 내적 결과:\n', dot_product)

output

행렬 내적 결과:
 [[ 58  64]
 [139 154]]

전지 행렬

원 행렬에서 행과 열 위치를 교환한 원소로 구성한 행렬은 전치행렬이라고 한다.

전치 행렬은 transpose() 를 이용해 구한다.

예시를 보면 쉽게 이해할 수 있다.

A = np.array([[1, 2, 3],
              [4, 5, 6]])
transpose_A = np.transpose(A)
print('A의 원본 행렬:\n', A)
print('A의 전치 행렬:\n', transpose_A)

output

A의 원본 행렬:
 [[1 2 3]
 [4 5 6]]
A의 전치 행렬:
 [[1 4]
 [2 5]
 [3 6]]

0개의 댓글