6. axis의 이해 - axis를 파라미터로 갖는 함수 -
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 bounds로 axis 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차원 벡터가 반환된 것을 볼 수 있다.