HOWTO · NumPy

NumPy 배열의 허수

이 튜토리얼은 허수를 numpy 배열에 저장하는 방법을 보여줍니다.

이 페이지의 내용

Python에서 복소수 리터럴의 허수부는 2j처럼 j로 표시합니다. NumPy 배열은 이러한 복소수를 저장하고 요소별 산술 연산을 수행하며, 각 값의 실수부와 허수부를 제공합니다. 값이 이미 정해져 있다면 복소수 리터럴을 사용하고, 실수 입력으로 배열을 만들되 나중에 복소수 결과를 담아야 한다면 복소 dtype을 선택하세요.

복소수가 포함된 NumPy 배열 만들기

허수는 실수부가 없는 수이고, 복소수는 실수부와 허수부를 함께 갖는 수입니다. Python에서 j 접미사는 허수부를 나타내므로 2j는 순허수이고 1 + 2j는 두 성분을 모두 가집니다. 복소수 리터럴로 배열을 만들면 NumPy는 복소수 요소 형식을 추론합니다. 시작 데이터에 실수부와 허수부가 모두 들어 있는 경우에 유용합니다.

다음 예제를 실행해 보세요.

import numpy as np

values = np.array([1 + 2j, 3 + 4j, 5 + 6j])
print(values)
[1.+2.j 3.+4.j 5.+6.j]

배열에는 값이 세 개 있습니다. 출력된 각 요소에서 부호 앞의 숫자는 실수부이고 j에 붙은 숫자는 허수부입니다. NumPy의 간결한 표시는 값을 표현하는 방식일 뿐, Python의 j 표기법을 바꾸지는 않습니다. 리터럴을 쓸 때는 허수 항에 j 접미사를 붙이세요. 1 + 2라고 쓰면 어느 항에도 허수 표시가 없으므로 일반 실수가 됩니다.

배열을 초기화할 때 복소수 dtype 선택하기

배열을 실수로 시작하더라도 나중에 복소수 결과를 보존해야 한다면 초기화할 때 복소 dtype을 지정하세요. 예를 들어 np.ones(3, dtype=complex)는 실수 1로 초기화된 복소수 요소 세 개를 만듭니다. 실수만 있는 입력에서 NumPy가 형식을 추론하게 두면 결과 배열은 실수 dtype을 갖습니다. 실수 배열에 복소수를 대입해도 허수부를 보존할 수 없습니다. 처음부터 형식을 지정하면 이러한 손실을 막고 배열의 용도도 분명해집니다.

이 설정은 허수부를 추가하는 별도의 연산이 아니라 배열 요소의 형식을 정하는 것입니다. 허수부가 0인 복소수도 복소수 형식의 배열에 들어갈 수 있습니다. 반대로 1.0처럼 실수로 보이는 값만으로 배열이 복소수가 되지는 않습니다. 데이터가 실수이지만 이후 계산이나 대입에서 복소수가 필요하다면 dtype=complex를 사용하세요. 초기 값에 이미 허수부가 있다면 복소수 리터럴을 직접 사용하면 됩니다. NumPy가 해당 값에서 복소수 형식을 추론할 수 있습니다.

복소수 배열에서 산술 연산하기

두 배열의 모양이 서로 호환되면 NumPy는 표준 산술 연산자를 요소별로 적용합니다. 다음 전체 예제는 배열 두 개를 만들고 합, 차, 곱, 몫을 계산합니다. 각 연산 결과는 새 배열이며, 복소수 나눗셈은 복소수의 일반적인 계산 규칙을 따릅니다. 분모의 요소가 0이 되지 않도록 입력값을 정했습니다. 예제에 출력되는 Addition, Subtraction, Multiplication, Division은 각각 합, 차, 곱, 몫을 가리키는 영어 레이블이며, 코드와 출력은 변경하지 않아 레이블도 영어로 표시됩니다.

import numpy as np

left = np.array([1 + 2j, 3 + 4j])
right = np.array([2 + 3j, 4 + 5j])

added = left + right
subtracted = left - right
multiplied = left * right
divided = left / right

print("Addition:", added)
print("Subtraction:", subtracted)
print("Multiplication:", multiplied)
print("Division:", divided)
Addition: [3.+5.j 7.+9.j]
Subtraction: [-1.-1.j -1.-1.j]
Multiplication: [-4. +7.j -8.+31.j]
Division: [0.61538462+0.07692308j 0.7804878 +0.02439024j]

두 배열의 모양이 같으므로 같은 위치의 요소끼리 짝을 이룹니다. 즉, left의 첫 번째 요소는 right의 첫 번째 요소와 연산되고 두 번째 요소도 같은 방식으로 처리됩니다. 이는 요소별 산술 연산이며 행렬 곱셈은 아닙니다. 행렬 곱을 하려면 적절한 행렬 연산을 사용하세요. 나눗셈에서는 분모 값을 주의해야 합니다. 분모가 0이면 유한한 몫을 얻을 수 없으므로, 수행하려는 계산에 맞는 입력값을 선택하세요.

실수부와 허수부에 접근하기

복소수 NumPy 배열에서 .real과 .imag는 각각 실수부와 허수부의 배열 뷰를 제공합니다. 이후 계산에 한 성분만 필요하거나 두 성분을 따로 확인하고 싶을 때 유용합니다. 성분 배열은 원본과 요소 위치가 같으므로 각 배열의 인덱스 k는 원래 복소수 배열의 인덱스 k에 해당합니다.

import numpy as np

values = np.array([1 + 2j, 3 + 4j, 5 + 6j])
real_parts = values.real
imaginary_parts = values.imag

print("Real parts:", real_parts)
print("Imaginary parts:", imaginary_parts)

이 예제의 값에서 실수부는 1, 3, 5이고 허수부는 2, 4, 6입니다. 이 속성들은 기존 복소수 배열을 바꾸지 않고 각 성분을 분리해 제공합니다. 실수부 배열과 허수부 배열을 따로 가지고 있다면 real_parts + 1j * imaginary_parts로 복소수 배열을 만들 수 있습니다. 서로 대응하는 입력 배열의 모양이 호환되는지 확인하세요. 리터럴로 배열을 만들고, 명시적으로 복소 dtype을 지정하고, 요소별 연산을 수행하고, 각 성분에 접근하는 방법을 익히면 NumPy 배열의 허수 값을 다룰 때 필요한 일반적인 작업을 수행할 수 있습니다.