늘 헷갈리는 axis0, axis1

axis는 늘 헷갈립니다.

  • 왜 헷갈리는지 모르겠지만, 늘 헷갈려요(저는 알아요, 저만 그런것이 아닐것이라는 사실을 하하핫). 그래서 입력한 다음에도 제대로 되었는지를 늘 확인해야 합니다 새드. 그래서 여기에 적어두고 헷갈릴 때마다 보려고 합니다 하하하.
  • 사실 헷갈리는 이유는 꽤 명확합니다. 1) 한번 공부할 때, 제대로 공부하지 않았기 때문에, 2) 공부한 것을 정리해두지 않았기 때문 이죠. 저는 제가 블로그를 참 잘 만들었다고 생각합니다. 공부한 것들을 정리해두면서 더 많이 공부하게 되고, 내면이 탄탄해지는 기분이 들어요. 아마도, 올해 제일 잘한 일인 것 같네요.

테스트 어레이

  • 차원에 따른 변화를 명확하게 확인하기 위해서, np.array의 shape을 (2,3,5,7)의 소수들로 세팅했습니다. 이렇게 하면 차원이 어떻게 변화하는지 확인이 쉽습니다.
import numpy as np

"""차원에 따른 변화를 파악하기 위해서 각 축을 소수로 만들어서 4차원의 어레이를 생성
"""
test_arr = np.array([i for i in range(0, 2*3*5*7)]).reshape(2,3,5,7)
print("shape: {}".format(test_arr.shape))
print("---")
print(test_arr)
  • (2,3,5,7) 크기의 어레이가 생성되었습미다.
shape: (2, 3, 5, 7)
---
[[[[  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  36  37  38  39  40  41]
   [ 42  43  44  45  46  47  48]
   [ 49  50  51  52  53  54  55]
   [ 56  57  58  59  60  61  62]
   [ 63  64  65  66  67  68  69]]

  [[ 70  71  72  73  74  75  76]
   [ 77  78  79  80  81  82  83]
   [ 84  85  86  87  88  89  90]
   [ 91  92  93  94  95  96  97]
   [ 98  99 100 101 102 103 104]]]


 [[[105 106 107 108 109 110 111]
   [112 113 114 115 116 117 118]
   [119 120 121 122 123 124 125]
   [126 127 128 129 130 131 132]
   [133 134 135 136 137 138 139]]

  [[140 141 142 143 144 145 146]
   [147 148 149 150 151 152 153]
   [154 155 156 157 158 159 160]
   [161 162 163 164 165 166 167]
   [168 169 170 171 172 173 174]]

  [[175 176 177 178 179 180 181]
   [182 183 184 185 186 187 188]
   [189 190 191 192 193 194 195]
   [196 197 198 199 200 201 202]
   [203 204 205 206 207 208 209]]]]

axis에 따른 변화를 확인해봅시다: np.min

  • 사실 np.min이든 np.sum이든 아무 상관없습니다만, np.min이 axis에 따른 변화가 명확하게 드러나는 것 같아서, 선택했습니다.
  • 선택할 수 있는 axis는 [None, 0, 1,2,3]입니다. axis를 변화하면서 np.min을 사용하였는데 그 결과도 아래 함께 추가하였습니다.
    • axis=None: 이 경우, 축을 무시하고, 모든 원소가 같은 층위에 있다고 생각합니다. 따라서, 여기서는 해당 어레이에 존재하는 원소 중에서 가장 작은 원소를 리턴합니다.
    • axis=0: 이 경우 1번째 차원을 적용해 줍니다. array의 shape는 (2,3,5,7)이고, 2개 짜리 array에 대해서 해당 함수를 적용해줍니다.
    • axis=1: 이 경우 2번째 차원을 적용해 줍니다. array의 shape는 (2,3,5,7)이고, 3개 짜리 array에 대해서 해당 함수를 적용해줍니다.
    • axis=2: 이 경우 3번째 차원을 적용해 줍니다. array의 shape는 (2,3,5,7)이고, 5개 짜리 array에 대해서 해당 함수를 적용해줍니다.
    • axis=3: 이 경우 4번째 차원을 적용해 줍니다. array의 shape는 (2,3,5,7)이고, 7개 짜리 array에 대해서 해당 함수를 적용해줍니다.

실제 코드

new_arr = np.min(test_arr, axis=None)
print("axis=None:")
print("shape: {}".format(new_arr.shape))
print(new_arr)
print("---")
for axis_v in range(0, len(test_arr.shape)):
    new_arr = np.min(test_arr, axis=axis_v)
    print("axis={}:".format(axis_v))
    print("shape: {}".format(new_arr.shape))
    print(new_arr)
    print("---")
axis=None:
shape: ()
0
---
axis=0:
shape: (3, 5, 7)
[[[  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  36  37  38  39  40  41]
  [ 42  43  44  45  46  47  48]
  [ 49  50  51  52  53  54  55]
  [ 56  57  58  59  60  61  62]
  [ 63  64  65  66  67  68  69]]

 [[ 70  71  72  73  74  75  76]
  [ 77  78  79  80  81  82  83]
  [ 84  85  86  87  88  89  90]
  [ 91  92  93  94  95  96  97]
  [ 98  99 100 101 102 103 104]]]
---
axis=1:
shape: (2, 5, 7)
[[[  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]]

 [[105 106 107 108 109 110 111]
  [112 113 114 115 116 117 118]
  [119 120 121 122 123 124 125]
  [126 127 128 129 130 131 132]
  [133 134 135 136 137 138 139]]]
---
axis=2:
shape: (2, 3, 7)
[[[  0   1   2   3   4   5   6]
  [ 35  36  37  38  39  40  41]
  [ 70  71  72  73  74  75  76]]

 [[105 106 107 108 109 110 111]
  [140 141 142 143 144 145 146]
  [175 176 177 178 179 180 181]]]
---
axis=3:
shape: (2, 3, 5)
[[[  0   7  14  21  28]
  [ 35  42  49  56  63]
  [ 70  77  84  91  98]]

 [[105 112 119 126 133]
  [140 147 154 161 168]
  [175 182 189 196 203]]]
---

wrap-up

  • row, column으로 생각하면 오히려 더 헷갈리는 것 같습니다. 우리가 일반적으로 리스트를 생각하면 리스트 안에 또 리스트가 있는 형태로 차원이 구성되죠. 그리고 같은 리스트 내에 있는 원소들의 shape은 같아야 합니다(np.array에서).
  • 만약 axis=0이라면 해당 어레이의 첫번째 차원은 삭제되고 나머지 차원은 그대로 유지된다는 이야기가 되죠. 음, 이건 말로 하면 설명이 더 복잡해지는 것 같기도 한데, 그냥 위에 코드를 보는 게 더 좋을 것 같기도 하네요.

  • 그리고, axis는 반드시 integer여야 합니다. 혹시 2개 이상의 차원을 한번에 축소할 수 있는지 알아봤는데, 그건 안되는 것 같네요.
test_arr = np.array([i for i in range(0, 2*3*5*7*11*13*17)]).reshape(2,3,5,7,11,13,17)
print(test_arr.shape)

for axis_v in range(0, len(test_arr.shape)):
    new_arr = np.min(test_arr, axis=axis_v)
    print("axis={}:".format(axis_v))
    print("shape: {}".format(new_arr.shape))
    print("---")
(2, 3, 5, 7, 11, 13, 17)
axis=0:
shape: (3, 5, 7, 11, 13, 17)
---
axis=1:
shape: (2, 5, 7, 11, 13, 17)
---
axis=2:
shape: (2, 3, 7, 11, 13, 17)
---
axis=3:
shape: (2, 3, 5, 11, 13, 17)
---
axis=4:
shape: (2, 3, 5, 7, 13, 17)
---
axis=5:
shape: (2, 3, 5, 7, 11, 17)
---
axis=6:
shape: (2, 3, 5, 7, 11, 13)
---

reference

댓글남기기