python/numpy

6. axis의 이해 - axis를 파라미터로 갖는 함수 -

Abokadoh 2023. 2. 16. 12:12

numpy의 많은 함수들은 axis라는 parameter를 갖는다.

 

axis을 의미하는 데, 이는 (dimension)차원의미한다.

 

예를 들어 2차원 행렬은 두개의 axis 0, 1 을 갖고, 1차원 벡터의 경우 축이 하나이므로 axis 0 하나만을 갖는다.

 

이 축에 대한 언급을 하지 않는다면, 전체 데이터에 대해 적용하겠다는 의미(None)가 되고 만약에 axis(축)을 언급한다면 해당 축에 따라서 연산을 적용하겠다는 의미가 된다.

 

오늘은 이 축에 따라서의 의미에 대해 공부해보겠다.

axis를 사용해서 연산을 적용하면 해당 axis에 따라서 연산이 적용되므로 결과해당 axis가 제외된 나머지 차원의 데이터만을 남기게 된다. 즉 결과의 차원은 언급된 axis의 개수만큼 감소된 값일 것이다.

# <in>
x = np.arange(15)
print(x)


# <out>
[ 0  1  2  3  4  5  6  7  8  9 10 11 12 13 14]

1차원 벡터 x를 만들었다. 1차원 벡터는 0 axis만을 갖는다. axis를 0으로 하고 연산을 적용해보자.

# <in>
x = np.arange(15)

np.sum(axis = 0)


# <out>
105

결과는 105, 1차원 벡터들의 모든 원소를 더한 결과가 나온다. 1차원의 경우 axis를 파라미터로 주지 않으면 default값인 None을 적용하기 때문에 이와 같은 결과를 볼 수 있다.

# <in>
a = np.arange(15)

np.sum(a) # axis를 입력하지 않으면 axis = None 으로 적용한다.


# <out>
105

그럼 1차원 벡터에 axis = 1을 파라미터로 주면 어떤 일이 발생하는지 보겠다.

# <in>
x = np.arange(15)
np.sum(x, axis = 1)


# <out>
AxisError: axis 1 is out of bounds for array of dimension 1

AxisError가 발생한다. out of boundsaxis 1 값이 범위 밖의 값이라는 의미이다.

 

이제 2차원 행렬에 적용해보자.

# <in>
y = x.reshape(3, 5)
print(y)
np.sum(y)


# <out>
[[ 0  1  2  3  4]
 [ 5  6  7  8  9]
 [10 11 12 13 14]]

105

3X5 2차원 행렬에 axis = None 으로 sum 연산을 하면 각 원소를 다 더한 결과를 보여준다.

# <in>
y = x.reshape(3, 5)
print(y)
np.sum(y, axis = 0)


# <out>
[[ 0  1  2  3  4]
 [ 5  6  7  8  9]
 [10 11 12 13 14]]

array([15, 18, 21, 24, 27])

axis = 0을 주고 연산을 하면 같은 열에 있는 원소를 다 더하여 1차원 벡터로 나타낸다.

# <in>
y = x.reshape(3, 5)
print(y)
np.sum(y, axis = 1)


# <out>
[[ 0  1  2  3  4]
 [ 5  6  7  8  9]
 [10 11 12 13 14]]

array([10, 35, 60])

axis = 1을 주고 연산을 하면, 같은 행에 있는 원소를 다 더하여 1차원 벡터로 나타난다.

# <in>
y = x.reshape(3, 5)
print(y)
np.sum(y, axis = 2)

# <out>
AxisError: axis 2 is out of bounds for array of dimension 2

2차원 벡터의 axis =2를 주면, 역시 AxisError가 발생한다.

 

 

이제 3차원 텐서에 axis를 넣어 연산해보자.

# <in>
z = np.arange(36).reshape(3, 4, 3)
print(z)
np.sum(z)


# <out>
[[[ 0  1  2]
  [ 3  4  5]
  [ 6  7  8]
  [ 9 10 11]]

 [[12 13 14]
  [15 16 17]
  [18 19 20]
  [21 22 23]]

 [[24 25 26]
  [27 28 29]
  [30 31 32]
  [33 34 35]]]

630

axis = None에서 연산하면 각 원소를 모두 더scalar값을 뱉는다.

# <in>
z = np.arange(36).reshape(3, 4, 3)
print(z)
np.sum(z, axis=0)


# <out>
[[[ 0  1  2]
  [ 3  4  5]
  [ 6  7  8]
  [ 9 10 11]]

 [[12 13 14]
  [15 16 17]
  [18 19 20]
  [21 22 23]]

 [[24 25 26]
  [27 28 29]
  [30 31 32]
  [33 34 35]]]

array([[36, 39, 42],
       [45, 48, 51],
       [54, 57, 60],
       [63, 66, 69]])

axis =0을 적용하고 연산하면 같은 같은 위치에 있는 원소끼리의 합으로 이루어진 2차원 행렬을 뱉는다.

# <in>
z = np.arange(36).reshape(3, 4, 3)
print(z)
np.sum(z, axis =1)


# <out>
[[[ 0  1  2]
  [ 3  4  5]
  [ 6  7  8]
  [ 9 10 11]]

 [[12 13 14]
  [15 16 17]
  [18 19 20]
  [21 22 23]]

 [[24 25 26]
  [27 28 29]
  [30 31 32]
  [33 34 35]]]

array([[ 18,  22,  26],
       [ 66,  70,  74],
       [114, 118, 122]])

axis = 1을 적용하면 각 행렬의 행들을 더한 2차원 행렬을 뱉는다.

# <in>
z = np.arange(36).reshape(3, 4, 3)
print(z)
np.sum(z, axis=1)


# <out>
[[[ 0  1  2]
  [ 3  4  5]
  [ 6  7  8]
  [ 9 10 11]]

 [[12 13 14]
  [15 16 17]
  [18 19 20]
  [21 22 23]]

 [[24 25 26]
  [27 28 29]
  [30 31 32]
  [33 34 35]]]

array([[  3,  12,  21,  30],
       [ 39,  48,  57,  66],
       [ 75,  84,  93, 102]])

axis =2를 적용하고 연산하면 각 행렬의 열들을 더한 값인 2차원 행렬을 뱉는다.

 

axis의 값을 튜플로 묶어서 명령할 수도 있다.

 

튜플에 명시된 모든 axis(축값)에 대해서 연산한다고 생각하면 쉽다. 당연히 튜플에 명시된 axis의 개수만큼 결과값의 차원도 줄어들 것이다.

# <in>
z = np.arange(36).reshape(3, 4, 3)
print(z)
np.sum(z,(0,2))


# <out>
[[[ 0  1  2]
  [ 3  4  5]
  [ 6  7  8]
  [ 9 10 11]]

 [[12 13 14]
  [15 16 17]
  [18 19 20]
  [21 22 23]]

 [[24 25 26]
  [27 28 29]
  [30 31 32]
  [33 34 35]]]

array([117, 144, 171, 198])

3차원 텐서에서 axis 0과 axis 2 두 차원에 대한 연산을 통해 2차원 줄어든 1차원 벡터가 반환된 것을 볼 수 있다.