본문 바로가기

Machine Learning_모델설계_Python

Numpy_2 배열 연산, 장단점

안녕하세요 배도리입니다. 배열 객체 다루기에 이어서 이번에는 배열연산에 대해 알아보겠습니다. 이전에 설명했던 것처럼 넘파이는 수학계산에 상당히 강합니다. 어떻게 연산이 진행되는지와 어떤 연산이 있는지 확인하겠습니다.

배열 연산

1. 연산함수(Operation function) 

배열 내부 연산을 지원하는 함수입니다.

▪ 축(axis): 배열의 랭크가 증가할 때마다 새로운 축이 추가되어 차원이 증가합니다.(axis=0은 열로 기준 1은 행으로 기준 )

이게 저는 헷갈리더라구요. 2찬원이나 테이블에서 axis=0은 세로라고 생각하고 axis=1은 가로라고 생각하면 될것 같습니다.

axis=0,1의 방향

만일 3차원이라면? (2,7,6) 인 3차원 텐서일 경우 axis=02, axis=17, axis=26 이되겠습니다.

▪ sum 함수: 각 요소의 합을 반환합니다.

test_array = np.arange(1,13).reshape(3,4)
test_array
array([
[ 1, 2, 3, 4],
[ 5, 6, 7, 8],
[ 9, 10, 11, 12]])
 
 
test_array.sum(axis=0) #열기준 1+5+9, 2+6+10, ..세로라고생각 세로로 내려가서 연산
array([15, 18, 21, 24])
 
test_array.sum(axis=1) #행기준 1+2+3+4, 5+6+7+8...가로라고생각 가로로가서 연산
array([10, 26, 42])
 

 

▪ 다른 연산 함수들로 mean, std, sqrt가 가능합니다.

test_array.mean(axis=1) #axis=1 행을 기준으로 평균 연산
array([ 2.5, 6.5, 10.5])
 
test_array.std() #전체 값에 대한 표준편차 연산
3.452052529534663
 
test_array.std(axis=0) #axis=0 을 기준으로 표준편차 연산
array([3.26598632, 3.26598632, 3.26598632, 3.26598632])
 
np.sqrt(test_array) #각 요소에 제곱근 연산 수행
array([[1. , 1.41421356, 1.73205081, 2. ],
[2.23606798, 2.44948974, 2.64575131, 2.82842712],
[3. , 3.16227766, 3.31662479, 3.46410162]])
 

 

 

2. 연결 함수(concatenation functions)

두 객체 간의 결합을 지원합니다.

▪ vstack 함수: 배열을 수직으로 붙여 하나의 행렬을 생성합니다.

▪ hstack 함수: 배열을 수평으로 붙여 하나의 행렬을 생성합니다.

v1 = np.array([1, 2, 3])
v2 = np.array([4, 5, 6])
np.vstack((v1, v2))
array(
[[1, 2, 3],
[4, 5, 6]])
 
np.hstack((v1,v2))
array([1, 2, 3, 4, 5, 6])
 

 

▪ concatenate 함수: 축을 고려하여 두 개의 배열을 결합합니다.

- 스택(stack) 계열의 함수와 달리 생성될 배열과 소스가 되는 배열의 축방향 차원이 같아야 합니다.

- 두벡터를 결합하고 싶다면, 해당 벡터를 일단 2차원 배열 꼴로 변환 후 행렬로 나타내야 합니다.

v1 = np.array([1, 2, 3, 4]).reshape(2,2)
v1
array(
[[1, 2],
[3, 4]])
 
v2 = np.array([[5,6]]).T #트렌스포스
v2
array(
[[5],
[6]])
 
np.concatenate((v1,v2), axis=1) #  가로로 가니까 행기준 행개수가 같으면 진행 v1 행두개 v2 행두개 연산가
array(
[[1, 2, 5],
[3, 4, 6]])
 

 

 

3. 사칙연산 함수

▪ 넘파이는 파이썬과 동일하게 배열 간 사칙연산 지원합니다.

- 행렬과 행렬, 벡터와 백터 간 사칙연산이 가능합니다.

- 같은 배열의 구조일 때 요소별 연산(element-wise operation)

- 요소별 연산 : 두 배열의 구조가 동일할 경우 같은 인덱스 요소들끼리 연산합니다.

x = np.arange(1, 7).reshape(2,3)
x
array(
[[1, 2, 3],
[4, 5, 6]])
 
x + x  #덧셈 뺄셈 나눗셈 제곱 가능
array(
[[ 2, 4, 6],
[ 8, 10, 12]])

 

▪ 배열 간의 곱셈에서는 요소별 연산과 벡터의 곱셉(dot product) 연산 가능합니다.

- 두 개의 행렬에서 첫 번째 행렬의 열 크기와 두 번째 행렬의 행 크기가 동일해야합니다.

- m×n 행렬과 n×l 행렬, 벡터의 내적 연산하면 m×l의 행렬 생성 (m x n) • (nk) = (m x k)

x_1 = np.arange(1, 7).reshape(2,3) # 2 x 3
x_1
array(
[[1, 2, 3],
[4, 5, 6]]) 
 
x_2 = np.arange(1, 7).reshape(3,2) # 3 x 2
x_2
array(
[[1, 2],
[3, 4],
[5, 6]])
 
x_1.dot(x_2) # 2 x 2
array(
[[22, 28],
[49, 64]])

 

 

▪ 브로드캐스팅 연산(broadcasting operations): 하나의 행렬과 스칼라 값들 간의 연산이나 행렬과 벡터 간의 연산입니다.

• 방송국의 전파가 퍼지듯 뒤에 있는 스칼라 값이 모든 요소에 퍼지듯이 연산합니다.

- 행렬과 스칼라 값 외에 행렬과 벡터, 벡터와 벡터 간에도 연산합니다.

x = np.arange(1, 10).reshape(3,3)
x
array([[1, 2, 3], [4, 5, 6], [7, 8, 9]])
 
x + 10
array([[11, 12, 13], [14, 15, 16], [17, 18, 19]])
 
v = np.arange(10 , 40 , 10)
v
array([10, 20, 30])
 
x + v
array([[11, 22, 33],
[14, 25, 36],
[17, 28, 39]])

 

 

 

넘파이(NumPy) – 성능의 장단점

1. 넘파이의 텐서 연산의 장점

▪ C와 유사한 형태로 메모리를 관리하면서 C와 같은 연산 속도로 계산할 수 있습니다.

- 메모리 구조상 요소들이 붙어있기 때문입니다.

- 파이썬의 가장 큰 특징인 동적 타이핑을 포기했지만, C로 구현되어 있어 배열 연산에 있어 매우 큰 성능적 우위 확보합니다.

- 대용량 배열 연산에서 넘파이가 사실상 표준으로 사용됩니다.

 

2. 넘파이의 텐서 연산의 단점

▪ 연결 연산처럼 여러 배열을 붙이는 연산에서는 일반적인 리스트에 비해 느립니다.

- 필요할 때마다 메모리 탐색 과정으로 새로운 공간을 잡아야 하기 때문입니다.