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

NumPy 배열 완벽 가이드: 초보자를 위한 입문서

리스트는 요소들이 순서대로 저장된 자료형으로, 여러 개의 관련 값을 하나의 변수에 담을 수 있어 매우 유용합니다. 예를 들어 신발 10켤레의 이름을 하나의 변수에 저장하거나, 매장에서 구매한 물건 목록을 하나의 변수에 보관할 수 있습니다.

하지만 파이썬 기본 리스트만으로는 처리하기 어려운 고급 작업도 있습니다. 바로 이럴 때 NumPy의 배열(array) 자료형이 빛을 발합니다. NumPy 라이브러리를 활용하면 다차원 배열을 손쉽게 만들 수 있습니다.

이 글에서는 NumPy 배열이 무엇인지, 왜 유용한지, 그리고 코드에서 어떻게 다루는지 하나씩 살펴보겠습니다.

NumPy 배열이란?

NumPy 배열은 파이썬 라이브러리인 NumPy에서 사용되는 배열 객체입니다. NumPy는 'Numerical Python'의 약자로, 과학 및 수학 계산에 널리 쓰이는 패키지이며 데이터 분석과 고급 수학 연산을 돕는 다양한 도구를 함께 제공합니다.

외부 패키지 없이 순수 파이썬(vanilla Python)에서 제공하는 기본 배열도 강력하지만, 처리 속도가 느릴 수 있습니다. 반면 NumPy 배열은 일반적인 파이썬 배열보다 몇 배나 빠른 속도를 내도록 설계되었습니다.

이러한 성능 향상이 가능한 이유는 NumPy 배열이 값을 메모리의 연속된 공간에 저장하기 때문입니다. 덕분에 파이썬이 데이터에 더 쉽고 빠르게 접근하고 조작할 수 있습니다.

NumPy 배열 선언하는 방법

먼저 간단한 NumPy 배열을 만들어 보겠습니다. 이 튜토리얼에서는 문자열 값들을 배열에 저장해 볼 텐데요, 카페에서 판매하는 디저트 목록을 예로 들겠습니다. 우선 NumPy 라이브러리를 임포트합니다:

import numpy as np

이 코드는 numpy를 임포트하고 라이브러리에 np라는 별칭을 붙입니다. 따라서 이후에는 배열을 다룰 때마다 np만 호출하면 됩니다.

다음으로 array 인터페이스를 사용해 배열을 선언합니다:

treats = np.array(["Blueberry Muffin", "Cinnamon Bun", "Jammy Shortbread"])
print(treats)

배열에는 세 개의 문자열 값이 들어 있습니다. 일반 파이썬 리스트처럼 모든 항목을 대괄호로 감싸고, NumPy 배열을 선언하기 위해 np에 포함된 array 메서드를 사용했습니다. 이렇게 하면 NumPy의 기본 배열 타입인 ndarray 객체가 생성됩니다.

위 코드를 실행하면 원본 배열이 NumPy 배열로 변환된 결과가 출력됩니다:

['Blueberry Muffin' 'Cinnamon Bun' 'Jammy Shortbread']

이제 우리가 자유롭게 다룰 수 있는 배열이 준비되었습니다!

NumPy 배열의 차원(Dimension)

여기서 말하는 차원은 영화에 나오는 세계 같은 것이 아니라, 배열 안의 깊이(depth) 단계를 의미합니다. 즉, 차원이라는 용어는 중첩 배열(nested array), 즉 배열 안에 또 다른 배열이 포함된 구조를 가리킵니다.

배열은 원하는 만큼 많은 차원을 가질 수 있지만, 실무에서 주로 다루는 배열은 대부분 1차원(1-D), 2차원(2-D), 3차원(3-D)입니다. 여기서 'D'는 dimension(차원)을 뜻합니다.

NumPy 1차원(1-D) 배열

앞선 첫 번째 예제에서 만든 것은 1차원 배열입니다. 1차원 배열은 0차원 배열(즉, 개별 항목)들을 요소로 가지는 배열입니다. 우리가 다루는 대부분의 배열은 이 1차원 형태입니다.

카페 디저트의 가격을 저장하는 배열을 만들어 보겠습니다:

import numpy as np

prices = np.array([1.95, 2.00, 2.05])
print(prices)

코드를 실행하면 값들이 1차원 배열에 저장된 결과가 출력됩니다: [1.95 2. 2.05]

1차원 배열의 요소에 접근하는 방법은 파이썬 리스트와 동일합니다. 두 번째 항목을 가져와 볼까요?

print(prices[1])

이 코드는 인덱스 1에 해당하는 항목, 즉 2를 반환합니다.

NumPy 2차원(2-D) 배열

모든 배열이 1차원인 것은 아닙니다. 예를 들어 두 개의 배열을 하나의 배열에 담고 싶다고 가정해 봅시다. 하나는 카페에서 판매하는 디저트 목록, 다른 하나는 커피 목록이며, 이 둘을 합쳐 menu_items(메뉴 항목) 배열로 만드는 것입니다.

NumPy로 이 배열을 만들어 보겠습니다:

import numpy as np

menu_items = np.array([
	["Blueberry Muffin", "Cinnamon Bun", "Jammy Shortbread"],
	["Cappuccino", "Espresso", "Mocha"]
])

print(menu_items)

실행 결과는 다음과 같습니다:

[['Blueberry Muffin' 'Cinnamon Bun' 'Jammy Shortbread']
 ['Cappuccino' 'Espresso' 'Mocha']]

방금 만든 배열은 2차원입니다. 배열 안의 첫 번째 배열은 디저트 목록을, 두 번째 배열은 커피 목록을 담고 있으며, 두 배열이 하나의 대괄호로 묶여 있는 것을 확인할 수 있습니다.

2차원 배열에서 요소를 꺼내는 방법은 파이썬과 조금 다릅니다. 2차원 배열의 요소에 접근하려면 가져오려는 값의 인덱스 번호들을 쉼표로 구분해서 지정해야 합니다.

다음 코드를 살펴보세요:

print(menu_items[0, 2])

실행 결과는 'Jammy Shortbread'입니다. 인덱스 0번 배열 안에서 인덱스 2에 해당하는 항목을 가져온 것으로, 디저트 배열의 마지막 항목이 조회됩니다.

NumPy 3차원(3-D) 배열

이번에는 차원을 하나 더 추가해 보겠습니다! NumPy 배열은 2차원 배열들을 포함하는 3차원 배열도 가질 수 있습니다.

예를 들어 다음 값들을 저장한다고 가정해 봅시다:

  • 달콤한 음식과 달지 않은 음식 (각각 별도의 배열로 묶음)
  • 카페인 음료와 카페인 없는 음료 (각각 별도의 배열로 묶음)

이 모든 값들은 하나의 배열 안에 저장됩니다. 각 차원의 구성은 다음과 같습니다:

  • 1차원: 전체 메뉴 항목
  • 2차원: 달콤한 음식 달지 않은 음식, 카페인 음료 카페인 없는 음료
  • 3차원: 달콤한 음식, 달지 않은 음식, 카페인 음료, 카페인 없는 음료

NumPy로 이 배열을 만들어 보겠습니다. 아래 코드를 파이썬 파일에 붙여 넣으세요:

import numpy as np

menu_items = np.array([
	[
		["Blueberry Muffin", "Cinnamon Bun", "Jammy Shortbread"],
		["Smoked Bacon Roll", "Tuna Melt Panini", "Cheese and Tomato Toastie"]
	],
	[
		["Cappuccino", "Espresso", "Mocha"],
		["Apple Juice", "Water", "Orange Juice"]
	]
])

print(menu_items)

실행 결과:

[[['Blueberry Muffin' 'Cinnamon Bun' 'Jammy Shortbread']
  ['Smoked Bacon Roll' 'Tuna Melt Panini' 'Cheese and Tomato Toastie']]

 [['Cappuccino' 'Espresso' 'Mocha']
  ['Apple Juice' 'Water' 'Orange Juice']]]

앞서 설명한 모든 정보를 담은 3차원 배열이 완성되었습니다. 이 배열은 카페 메뉴 전체를 한눈에 볼 수 있는 종합 목록입니다.

3차원 배열에서 항목에 접근하는 방법도 2차원 배열과 비슷합니다. 다만 세 번째 인덱스까지 지정해야 한다는 점이 다릅니다. 배열에서 'Mocha'를 꺼내 보겠습니다:

print(menu_items[1, 0, 2])

실행 결과는 'Mocha'입니다.

첫 번째 인덱스 1은 접근하려는 1차원(음료 배열)을, 두 번째 인덱스 0은 2차원(카페인 음료 배열)을, 세 번째 인덱스 2는 3차원(Mocha 항목)을 가리킵니다.

배열의 차원 개수 확인하기

차원이 늘어날수록 배열의 구조는 점점 복잡해 보일 수 있습니다. 사실 우리는 아직 3차원을 넘는 배열조차 살펴보지 않았습니다! 다행히 배열이 몇 차원인지 손쉽게 확인할 수 있는 방법이 있습니다.

아래 코드를 파이썬 파일에 붙여 넣고 실행해 보세요:

import numpy as np

menu_items = np.array([
	["Blueberry Muffin", "Cinnamon Bun", "Jammy Shortbread"],
	["Cappuccino", "Espresso", "Mocha"]
])

print(menu_items.ndim)

코드를 실행하면 '2'가 출력됩니다. 이는 배열이 2차원이라는 뜻이며, 위 배열 구조를 분석해 보면 실제로 그렇다는 것을 알 수 있습니다.

마무리

NumPy 배열은 유사한 값들을 저장하는 유연한 방법으로, 전통적인 파이썬 배열보다 빠르고 효율적입니다. 또한 NumPy를 사용하면 다차원 배열도 손쉽게 다룰 수 있는데, 이는 순수 파이썬만으로 처리하기 어려운 작업입니다.

이제 여러분도 전문가처럼 NumPy 배열을 활용할 준비가 되었습니다!