Computer >> 컴퓨터 >  >> 프로그래밍 >> Python

파이썬에서 Einstein 합산 규칙(einsum)으로 배열 축 합산하기

einsum() 메서드는 NumPy에서 아인슈타인 합산 규칙(Einstein summation convention)을 기반으로 연산을 수행하는 강력한 도구입니다. 이 규칙을 활용하면 행렬 곱셈, 전치, 내적, 특정 축의 합산 등 다양한 다차원 선형대수 배열 연산을 간결한 표기법 하나로 표현할 수 있습니다.

einsum()은 두 가지 모드로 동작합니다. 암시적(implicit) 모드에서는 표준적인 아인슈타인 합산 규칙에 따라 자동으로 계산이 수행됩니다. 반면 명시적(explicit) 모드에서는 화살표(->)를 사용해 출력 형태를 지정하며, 특정 첨자 라벨에 대한 합산을 비활성화하거나 강제함으로써 고전적인 아인슈타인 합산 범위를 넘어서는 다양한 배열 연산도 유연하게 처리할 수 있습니다.

주요 파라미터

  • subscripts (첫 번째 매개변수): 합산에 사용할 첨자 라벨들을 쉼표로 구분된 문자열로 지정합니다. 예를 들어 'ij->i'처럼 입력 차원과 출력 차원을 정의합니다.
  • operands (두 번째 매개변수): 연산 대상이 되는 배열들입니다.

구현 단계

1단계: 필수 라이브러리 임포트

import numpy as np

2단계: NumPy 배열 생성

arange()와 reshape() 메서드를 사용하여 4×4 크기의 2차원 배열을 만듭니다.

arr = np.arange(16).reshape(4,4)

3단계: 배열 확인

print("Our Array...\n",arr)

4단계: 차원 확인

print("\nDimensions of our Array...\n",arr.ndim)

5단계: 데이터 타입 확인

print("\nDatatype of our Array object...\n",arr.dtype)

6단계: 형태(shape) 확인

print("\nShape of our Array object...\n",arr.shape)

7단계: einsum()으로 축 합산 수행

아인슈타인 합산 규칙을 적용해 특정 축(axis)을 따라 합산하려면 numpy.einsum() 메서드를 사용합니다. 여기서 'ij->i'는 j축(열 방향)을 따라 값을 모두 더하고 i축(행)만 남긴다는 의미로, 각 행별 합계가 결과로 반환됩니다.

print("\nResult...\n",np.einsum('ij->i', arr))

전체 예제 코드

import numpy as np

# arange()와 reshape()로 NumPy 배열 생성
arr = np.arange(16).reshape(4,4)

# 배열 출력
print("Our Array...\n",arr)

# 차원 확인
print("\nDimensions of our Array...\n",arr.ndim)

# 데이터 타입 확인
print("\nDatatype of our Array object...\n",arr.dtype)

# 형태(shape) 확인
print("\nShape of our Array object...\n",arr.shape)

# 아인슈타인 합산 규칙으로 배열 축 합산 수행
print("\nResult...\n",np.einsum('ij->i', arr))

실행 결과

Our Array...
[[ 0  1  2  3]
 [ 4  5  6  7]
 [ 8  9 10 11]
 [12 13 14 15]]

Dimensions of our Array...
2

Datatype of our Array object...
int64

Shape of our Array object...
(4, 4)

Result...
[ 6 22 38 54]

결과 해석

실행 결과를 보면 각 행의 요소들이 합산되어 출력되었습니다.

  • 첫 번째 행: 0 + 1 + 2 + 3 = 6
  • 두 번째 행: 4 + 5 + 6 + 7 = 22
  • 세 번째 행: 8 + 9 + 10 + 11 = 38
  • 네 번째 행: 12 + 13 + 14 + 15 = 54

즉, 'ij->i' 첨자 표기는 열 방향(j)을 따라 합산하여 행별 합계를 구하는 것으로, np.sum(arr, axis=1)과 동일한 결과를 제공합니다. 이처럼 einsum()은 직관적인 첨자 표기만으로 복잡한 배열 연산을 손쉽게 표현할 수 있어 성능 최적화와 코드 가독성 측면에서 유용하게 활용됩니다.