[데이터분석] 행렬연산
목차
- 1. 행렬 연산
- 1-1. 연산자
- 1-2. arange
- 1-3. sort
- 1-4. 숫자의 단일연산
1. 행렬연산
1-1. 연산자
연산자를 사용해서 배열간의 덧셈, 뺄셈, 곱셈, 나눗셈, 내적(점곱)을 수행할 수 있다. 이 연산들은 일반적으로 Numpy 배열에서 동일한 위치의 원소들끼리 연산을 수행하며, 연산결과는 새로운 배열로 반환된다.
# 2차원 배열을 두 개 만들고 모양 확인하기
a= np.array([[1,2,3],
[2,3,4]])
b= np.array([[3,4,5],
[1,2,3]])
a.shape, b.shape
#((2, 3), (2, 3))
2행 3열로 동일한 모양임을 알 수 있다
# 행렬끼리 연산을 하면 같은 위치에 있는 요소들끼리 연산이 됨을 알 수 있다
a+b
# array([[4, 6, 8],
# [3, 5, 7]])
a-b
#array([[-2, -2, -2],
# [ 1, 1, 1]])
내적(점곱, dot product)
내적은 두 개의 배열 간에 맞닿는 위치의 원소들을 곱한 후 모두 더하는 연산이다.
Numpy에서는 np.dot()함수나 배열객체의 dot()메서드를 사용하여 내적을 계산 할 수 있다!
# 행만 같고 열이 다른 2차원 배열 만들기
a= np.array([[1, 2, 3],
[4, 5, 6],
[7, 8, 9]])
b= np.array([[1,2],
[3,4],
[5,6]])
a.shape, b.shape
# ((3, 3), (3, 2))
# result 변수에 Numpy의 dot()함수를 사용하여 배열 a, b의 내적을 계산하여 결과를 저장한다
result = np.dot(a, b)
print(result)
#[[ 22 28]
# [ 49 64]
# [ 76 100]]
>> a 1행 * b 1열, a 1행 * b 2열
a 2행 * b 1열, a 2행 * b 2열
a 3행 * b 1열, a 3행 * b 2열
1-2. arange
- NumPy의 arange() 함수는 지정된 범위 내에서 일정한 간격으로 값을 생성하여 1차원 배열을 생성
- 주어진 범위의 시작값부터 끝값 바로 앞까지 일정한 간격으로 값을 생성하며, 생성된 값들은 배열로 반환
# arange() 함수의 기본 문법은 다음과 같다:
numpy.arange(start, stop, step, dtype=None)
- start: 생성할 범위의 시작값. 이 값은 생성된 배열에 포함되지 않으며, 기본값은 0이다.
- stop: 생성할 범위의 끝값. 이 값도 생성된 배열애 포함되지 않는다.
- step: 값들 사이의 간격을 나타내는 스칼라 값. 기본값은 1이다.
- dtype: 생성된 배열의 데이터타입을 지정한다. 기본값은 None으로, 데이터타입은 자동으로 추론된다.
예시) np.arange(0, 10, 2) 는 0부터 10 미만의 범위에서 2씩 증가하는 값을 생성하여 [0, 2, 4, 6, 8] 배열을 반환한다.
반복문을 사용하지 않고 일정한 간격의 값들을 생성할 수 있다는 점이 편리함!
# range 함수 사용시
arr1 = range(1, 11)
arr1
# range(1, 11)
for i in arr1:
print(i, end=' ')
# 1 2 3 4 5 6 7 8 9 10
# arange함수 사용시
arr2 = np.arange(1, 11)
arr2
# array([ 1, 2, 3, 4, 5, 6, 7, 8, 9, 10])
for i in arr2:
print(i, end=' ')
# 1 2 3 4 5 6 7 8 9 10
1-3. sort
- NumPy 의 sort() 함수는 배열의 원소를 정렬하는 기능을 제공한다.
- 주어진 배열을 변경하여 정렬된 상태로 업데이트 한다.
# sort() 함수의 기본 문법은 다음과 같다:
numpy.sort(a, axis=-1, kind=None, order=None)
- a: 정렬할 배열
- axis: 정렬할 축을 지정. 기본값은 -1로, 마지막 축을 따라 정렬된다.
- kind: 정렬 알고리즘의종류를 지정. 기본값은 quicksort로, 빠른 정렬알고리즘을 사용한다.
- order: 정렬 순서를 지정한다. 정렬할 배열이 구조화된 데이터 타입을 갖는 경우에 사용한다.
# 배열 성
ndarr1= np.array([1, 10, 5, 7, 2, 4, 3, 6, 8, 9])
ndarr1
# array([ 1, 10, 5, 7, 2, 4, 3, 6, 8, 9])
# 오름차순 정렬 + 유지됨을 확인할 수 있다
np.sort(ndarr1)
# array([ 1, 2, 3, 4, 5, 6, 7, 8, 9, 10])
ndarr1
# array([ 1, 2, 3, 4, 5, 6, 7, 8, 9, 10])
# 문자열 역순으로 출력하기
str1= 'Python'
print(str1[:]) # 모든 문자를 슬라이싱
print(str1[::]) # 1: 정방향
print(str1[:: -1]) # -1 : 역방향
print(str1[4:1: -1]) # 4번 인덱스부터 1 직전까지 역순으로 가져오기
print(str1[4:: -1]) # 4번 인덱스부터 0까지 역순으로 가져오기
print(str1[4:: 1]) # 4번 인덱스부터 마지막 인덱스까지 정방향으로 가져오기
# Python
# Python
# nohtyP
# oht
# ohtyP
# on
np.sort(ndarr1)[::-1] # 오름차순 정렬한 후에 전부 가져오는데 역순으로. so, 10 부터 1까지
# array([10, 9, 8, 7, 6, 5, 4, 3, 2, 1])
# 2차원 배열
ndarr2d = np.array([[11, 10, 12, 9],
[3, 1, 4, 2],
[5, 6, 7, 8]])
ndarr2d.shape
# (3, 4)
# 행 정렬. axis=0은 행을 의미함
np.sort(ndarr2d, axis=0)
# array([[ 3, 1, 4, 2],
# [ 5, 6, 7, 8],
# [11, 10, 12, 9]])
# 열 정렬. axis=1은 열을 의미함
np.sort(ndarr2d, axis=1)
# array([[ 9, 10, 11, 12],
# [ 1, 2, 3, 4],
# [ 5, 6, 7, 8]])
# 열 정렬 내림차순
np.sort(ndarr2d, axis=1)[:,::-1]
# array([[12, 11, 10, 9],
# [ 4, 3, 2, 1],
# [ 8, 7, 6, 5]])
# 축의 마지막 방향
np.sort(ndarr2d, axis=-1)
# array([[ 9, 10, 11, 12],
# [ 1, 2, 3, 4],
# [ 5, 6, 7, 8]])
>> 'axis=-1' 은 배열의 마지막 축을 의미하므로, 배열의 차원이 어떻게 정의되었든지간에 항상 마지막 축을 가리킨다.
위와 같은 경우는 2차원 배열이기 때문에 마지막 축은 열이 된다. 그래서 열 정렬과 같은 결과가 나온다.
1-4. 숫자의 단일 연산
# 2차원 배열 a를 만들어준 후 a 에 숫자 연산 해보기
a = np.array([[1,2,3],
[4,5,6]])
a+3
# array([[4, 5, 6],
# [7, 8, 9]])
a-3
# array([[-2, -1, 0],
# [ 1, 2, 3]])
a*3
# array([[ 3, 6, 9],
# [12, 15, 18]])
a/3
# array([[0.33333333, 0.66666667, 1. ],
# [1.33333333, 1.66666667, 2. ]])
# 2차원 배열 b를 만들어준 후 a와 연산해보기
b= np.array([[3,3,3],
[3,3,3]])
a+b
# array([[4, 5, 6],
# [7, 8, 9]])