NumPy 의 구조화된 배열

NumPyBeginner
지금 연습하기

소개

이 실습에서는 NumPy 의 구조화된 배열 (structured arrays) 에 대해 배웁니다. 구조화된 배열은 데이터베이스 테이블이나 스프레드시트와 유사하게 이기종 데이터 (heterogeneous data) 를 다루는 강력한 기능입니다. 구조화된 배열의 각 요소는 행 (row) 으로 생각할 수 있으며, "필드 (fields)"라고 불리는 명명된 열 (column) 을 가집니다. 이를 통해 Python 내에서 직접 표 형식 데이터를 구성하고 조작하는 데 이상적입니다.

이 실습 전반에 걸쳐 WebIDE 에 제공된 structured_arrays.py 파일에서 Python 코드를 작성하고 실행하게 됩니다.

이것은 가이드 실험입니다. 학습과 실습을 돕기 위한 단계별 지침을 제공합니다.각 단계를 완료하고 실무 경험을 쌓기 위해 지침을 주의 깊게 따르세요. 과거 데이터에 따르면, 이것은 초급 레벨의 실험이며 완료율은 98%입니다.학습자들로부터 98%의 긍정적인 리뷰율을 받았습니다.

구조화된 배열 생성 및 접근

먼저 간단한 구조화된 배열을 만들어 보겠습니다. 구조화된 배열의 데이터 타입 (dtype) 은 튜플의 리스트로 정의됩니다. 각 튜플은 (이름, 데이터_타입) 형식으로 필드를 지정합니다. 이를 통해 문자열과 정수와 같이 서로 다른 데이터 타입을 동일한 배열에 저장할 수 있습니다.

왼쪽 패널의 파일 탐색기에서 structured_arrays.py 파일을 엽니다. 다음 코드를 추가하여 이름과 나이를 가진 사람들의 목록을 나타내는 구조화된 배열을 생성합니다.

## Create a structured array
data = np.array([('Alice', 25, 55.5), ('Bob', 30, 68.0)],
                dtype=[('name', 'U10'), ('age', 'i4'), ('weight', 'f4')])

print("Original Array:")
print(data)

## Access a specific field by its name
names = data['name']
print("\nNames field:")
print(names)

코드 설명:

  • import numpy as np: NumPy 라이브러리를 가져옵니다.
  • np.array([...], dtype=[...]): 배열을 생성합니다. 첫 번째 인자는 튜플의 리스트이며, 각 튜플 ('Alice', 25, 55.5)은 데이터의 한 행을 나타냅니다.
  • dtype=[('name', 'U10'), ('age', 'i4'), ('weight', 'f4')]: 이것이 핵심 부분입니다. 세 개의 필드를 정의합니다:
    • 'name': 최대 길이가 10 자인 유니코드 문자열 (U10).
    • 'age': 4 바이트 (32 비트) 정수 (i4).
    • 'weight': 4 바이트 (32 비트) 부동소수점 수 (f4).
  • data['name']: 필드 이름 (열 이름) 을 인덱스로 사용하여 특정 필드의 모든 값에 접근할 수 있으며, 이는 새로운 NumPy 배열을 반환합니다.

이제 파일을 저장하고 터미널에서 실행하여 출력을 확인합니다.

python structured_arrays.py

전체 구조화된 배열과 이름만 포함된 배열을 보여주는 다음 출력을 볼 수 있습니다.

Original Array:
[('Alice', 25, 55.5) ('Bob', 30, 68. )]

Names field:
['Alice' 'Bob']

필드 수정 및 인덱싱

구조화된 배열은 변경 가능 (mutable) 하므로 값을 수정할 수 있습니다. 전체 필드를 한 번에 수정하거나, 인덱스로 특정 요소를 접근한 후 해당 필드를 수정할 수 있습니다. 또한 원본 필드의 일부를 포함하는 새 배열을 만들 수도 있습니다.

structured_arrays.py 스크립트 끝에 다음 코드를 추가합니다.

## Modify the 'age' field
data['age'] = [26, 31]
print("\nArray after modifying age:")
print(data)

## Access a single element (the first row)
first_person = data[0]
print("\nFirst person's data:")
print(first_person)

## Create a new array with a subset of fields
subset = data[['name', 'weight']]
print("\nSubset of array (name and weight):")
print(subset)

코드 설명:

  • data['age'] = [26, 31]: 이 코드는 age 필드에 새 값 리스트를 할당하여 전체 열을 업데이트합니다.
  • data[0]: 배열의 첫 번째 요소 (행) 에 접근합니다. 결과는 해당 단일 행의 데이터를 보유하는 NumPy void scalar 입니다.
  • data[['name', 'weight']]: 필드 이름 리스트를 전달하여 여러 열을 선택할 수 있으며, 이는 해당 필드만 포함하는 새 구조화된 배열을 생성합니다.

파일을 저장하고 터미널에서 다시 실행합니다.

python structured_arrays.py

이제 수정된 배열과 부분 집합을 보여주는 새 섹션이 출력에 포함됩니다.

... (previous output) ...

Array after modifying age:
[('Alice', 26, 55.5) ('Bob', 31, 68. )]

First person's data:
('Alice', 26, 55.5)

Subset of array (name and weight):
[('Alice', 55.5) ('Bob', 68. )]

레코드 배열을 사용한 속성 접근

이름으로 인덱싱하는 것 (data['name'] 등) 은 강력하지만 장황할 수 있습니다. NumPy 는 레코드 배열 (np.recarray) 이라고 하는 ndarray의 특별한 하위 클래스를 제공합니다. 레코드 배열을 사용하면 필드를 속성으로 접근할 수 있으며, 점 표기법 (record_array.name 등) 을 사용하여 코드를 더 깔끔하고 읽기 쉽게 만들 수 있습니다.

레코드 배열을 직접 생성하거나 기존 구조화된 배열을 변환할 수 있습니다. 두 가지 방법을 모두 살펴보겠습니다. structured_arrays.py 끝에 다음 코드를 추가합니다.

## Convert the structured array to a record array using view()
record_array = data.view(np.recarray)

print("\nType of the new view:")
print(type(record_array))

## Access fields using attribute (dot) notation
print("\nAccessing names via attribute:")
print(record_array.name)

print("\nAccessing ages via attribute:")
print(record_array.age)

코드 설명:

  • data.view(np.recarray): .view() 메서드는 동일한 데이터를 보는 새 배열 객체를 생성합니다. np.recarray를 지정하면 구조화된 배열 데이터의 레코드 배열 뷰를 얻게 됩니다. 데이터는 복사되지 않습니다. 단지 데이터를 상호 작용하는 다른 방식일 뿐입니다.
  • record_array.name: 이것이 레코드 배열의 핵심 기능입니다. name 필드에 객체의 속성처럼 접근할 수 있습니다. 이는 record_array['name']과 동일합니다.

파일을 저장하고 실행합니다.

python structured_arrays.py

출력에는 이제 새 배열 뷰의 타입이 표시되고 속성 접근이 시연됩니다.

... (previous output) ...

Type of the new view:
<class 'numpy.recarray'>

Accessing names via attribute:
['Alice' 'Bob']

Accessing ages via attribute:
[26 31]

요약

이 실습에서는 NumPy 에서 구조화된 배열을 사용하는 기본 사항을 배웠습니다. 명명된 필드와 여러 데이터 타입을 가진 구조화된 배열을 생성하는 것부터 시작했습니다. 그런 다음 사전 스타일 키 인덱싱을 사용하여 특정 필드 (열) 에 접근하고 값을 수정하는 연습을 했습니다. 마지막으로 필드를 속성으로 접근할 수 있는 편리한 대안인 레코드 배열을 탐색하고 .view() 메서드를 사용하여 표준 구조화된 배열과 레코드 배열 간에 변환하는 방법을 배웠습니다.

구조화된 배열은 Python 을 사용한 과학 컴퓨팅 및 데이터 분석에서 복잡한 테이블 형식 데이터를 처리하는 데 필수적인 도구입니다.