np.newaxis로 차원을 올려 브로드 캐스트 연산

15798 단어 파이썬numpy
3차원의 np.array의 이미지가 잡혀, np.newaxis란 무엇인가, 라고 하는 의문으로부터 자신 나름의 이해를 적은 기사입니다. np.array의 이미지와 np.newaxis의 기본적인 부분을 쓴 전반 기사는 여기
이 기사에서는 np.newaxis의 사용 장소에 대해. 구체적으로는, 전반의 기사에서 최초로 말한, 2차원 벡터를 복수 늘어놓은 2차원 배열이 2개 있었을 때에 양자에 포함되는 벡터간의 거리의 제곱을 총당으로 구하는 계산을 해 봐.

STEP 3. 브로드캐스트



본제에 들어가기 전에 브로드캐스트에 관해. 모양이 다른 배열끼리의 연산을 불편하게 해 주는 녀석입니다.
>>> x = np.array([1, 2])  # よこ2たて1のベクトル
>>> A = np.array([[1, 2],
                  [3, 4],
                  [5, 6]])  # よこ2たて3の行列
>>> B = np.array([[1],
                  [2]])  # よこ1たて2の行列
>>> C = np.array([[[1],
                   [2]],

                  [[3],
                   [4]]])  # よこ1たて2奥行き2の3次元配列

>>> x + A  # よこ2たて3の行列になる
array([[2, 4],
       [4, 6],
       [6, 8]]) 
>>> x + B  # よこ2たて2の行列になる
array([[2, 3],
       [3, 4]])
>>> x + C  # よこ2たて2奥行き2の3次元配列になる
array([[[2, 3],
        [3, 4]],

       [[4, 5],
        [5, 6]]])



STEP 4. 차원을 올려 브로드캐스트 연산



주제로 돌아가서, np.newaxis는 무엇을 기쁜가? 라는 이야기입니다.

1차원 배열의 경우



시작하기에 1차원 배열로 생각하면, 「2개의 배열의 각 요소끼리의 총당 연산 결과를 새로운 축에 격납한다」 위해서 np.newaxis를 사용할 수 있다고 하는 것입니까.

예를 들어 $x=[1, 3, 5, 7]$ 과 $y=[2, 4, 6]$ 가 있어 $4\times3=12$거리의 총당 계산을 하고 싶을 때, np.newaxis로 $y $를 갓 3요코 1의 행렬로 변환하고 나서 $x$와 연산하면, 갓 3요코 4의 행렬이 브로드캐스트에 의해 얻을 수 있는 것입니다.
>>> x = np.array([1, 3, 5, 7])
>>> y = np.array([2, 4, 6])
>>> x[np.newaxis, :] + y[:, np.newaxis]  # xの要素とyの要素の総当たりで足し算する
array([[  3,  5,  7,  9],
       [  5,  7,  9, 11],
       [  7,  9, 11, 13]])
# x + y[:, np.newaxis] でも同じ



2차원 배열의 경우



그럼 2차원의 경우 어떻게 될까요?
아래와 같이 같은 차원의 가로 벡터(여기서는 2차원)가 세로로 배열된 배열이 2개 있다고 가정합니다.
>>> A = np.array([[1, 2],
                  [3, 4],
                  [5, 6]])
>>> B = np.array([[1, 1],
                  [2, 2]])

이 때 , 좋음 상태 에 np.newaxis 를 도입 하면 벡터 의 각 성분 각각 에 대해 , 총당 연산 을 할 수 있습니다 . 1차원 배열의 총당 연산을 동시에 여러 번 하는 이미지(위라면 $x$성분과 $y$성분).
>>> A[np.newaxis, :, :] - B[:, np.newaxis, :]  # x成分とy成分の総当たり引き算
array([[[ 0, 1],
        [ 2, 3],
        [ 4, 5]],

      [[[-1, 0],
        [ 1, 2],
        [ 3, 4]]])
# A - B[:, np.newaxis, :] でも同じ



제대로 브로드캐스트 해 주도록(듯이) 가지런히 하면, newaxis의 취하는 방법을 바꾸어도 같은 값을 얻을 수 있습니다.
>>> A.T[np.newaxis, :, :] - B[:, :, np.newaxis]  # x成分とy成分の総当たり引き算
array([[[ 0, 2, 4],
        [ 1, 3, 5]],

      [[[-1, 1, 3],
        [ 0, 2, 4]]])
# A.T - B[:, :, np.newaxis] でも同じ



주제



위의 2차원 벡터 세트 $A$와 $B$가 있었을 때, (벡터간 거리)$^2$를 총당으로 구합시다.
$(a_x, a_y)$와 $(b_x, b_y)$의 거리의 제곱은 $(a_x-b_x)^2+(a_y-b_y)^2$이므로, 우선 $x$성분끼리, $y$성분 서로의 뺄셈의 제곱을 총당으로 하면 된다. 그 후, $x$성분의 차이의 제곱과 $y$성분의 차이의 제곱을 더한다 = 새로운 축으로서 $A$에도 $B$에도 추가하지 않은 3번째의 축으로 sum 해 하면 좋다 입니다 (그림으로 이미지하는 것이 알기 쉽다).
>>> ((A.T[np.newaxis, :, :] - B[:, :, np.newaxis])**2).sum(axis=1)
array([[ 1, 13, 41],
       [ 1,  5, 25]])
# ((A.T - B[:, :, np.newaxis])**2).sum(axis=1) でもよい



이것은 지난번 의 제일 먼저 「기계 학습의 에센스」로부터 발췌해 온 식과 등가입니다.
또한 위에서 보았듯이, $A$나 $B$에 추가하는 newaxis의 위치는 고유하지 않으며, 다음과 같이 해도 같은 결과를 얻을 수 있습니다.
>>> ((A[np.newaxis, :, :] - B[:, np.newaxis, :])**2).sum(axis=2)
array([[ 1, 13, 41],
       [ 1,  5, 25]])
# ((A - B[:, np.newaxis, :])**2).sum(axis=2) でもOK

>>> ((A.T[:, np.newaxis, :] - B.T[:, :, np.newaxis])**2).sum(axis=0)
array([[ 1, 13, 41],
       [ 1,  5, 25]])

벡터간 거리를 구하려면 이 제곱근을 취하면 됩니다.

좋은 웹페이지 즐겨찾기