[Numpy] Structured Array

Hunie_07·2026년 3월 2일

Numpy

목록 보기
8/8
post-thumbnail

📌 Structured Array

  • 일반적인 배열과 달리, 배열의 각 요소가 여러 개의 필드를 가지는 구조체처럼 동작하는 복합 데이터 타입(composite dtype)
  • C 언어나 Python의 dict 또는 class 객체처럼 필드명을 가진 레코드를 배열의 원소로 쓰는 자료
  • 이 구조는 다음과 같은 경우에 매우 유용
    • 테이블 형식의 데이터를 다룰 때 (엑셀, CSV, DB 등)
    • 다양한 타입의 데이터를 하나의 배열에 담고 싶을 때
    • 고성능으로 다차원 필드 데이터를 조작하고 싶을 때
항목일반 배열구조화 배열pandas DataFrame
데이터 타입하나만필드별로 다르게 설정 가능컬럼마다 다르게
필드 이름 접근불가능가능가능
사용 용도수치 계산 중심테이블형 데이터고급 분석/시각화용
  • 일반 배열과 비교
    • 구성 : 여러 필드(이름, 타입) 가능 (일반 배열은 단일 타입)
    • 활용 : 테이블, DB 유사 데이터 처리 (일반 배열은 수치 계산 중심)
    • 필드 접근 : 필드 이름으로 접근 (일반 배열은 인덱스 접근)
    • 속도 : 필드 처리 때문에 약간 느림 (일반 배열은 빠름)
  • 구조화 배열을 활용하면
    • pandas의 데이터 프레임으로 쉽게 전환이 가능
    • 복잡한 테이블 데이터를 효율적으로 다룰 수 있고, 메모리 사용이나 연산 효율도 높음
    • 특정 컬럼만 빠르게 접근해서 처리하고 싶은 경우 매우 유용

예시 배열1

  • dtype 정의
    • 이름(name) : 문자열( 'U10' )
    • 나이(age) : 정수( 'i4' )
    • 키(height) : float
dtype = [('name', 'U10'), ('age', 'i4'), ('height', 'f4')]

# 배열 생성
data = np.array([('홍길동', 20, 178.5),
				 ('방자', 30, 182.3),
                 ('변학도', 27, 180)], dtype=dtype)

1️⃣ 필드 접근 및 연산

  • 특정 필드 접근 : 배열명[필드명]
    • Ex) data['name']
  • 연산 : 필드로 접근하여 연산함수 적용
    • Ex) data['height'].mean()
data['name']

- 출력

array(['홍길동', '방자', '변학도'], dtype='<U10')

나이 평균 출력

data['age'].mean()

- 출력

np.float64(25.666666666666668)

예시 배열2

std_dtype = [('name', 'U10'), ('math', 'i4'), ('sci', 'i4')]
stds = np.array([('철수', 90, 85),
                 ('영희', 95, 80),
                 ('돌이', 88, 92)
                ], 
                dtype=std_dtype)

2️⃣ 조건 필터링

과학 점수가 85점 이상인 학생 추출

  1. Boolean (Mask) 생성
stds['sci'] >= 85

- 출력

array([ True, False,  True])

  1. Mask 활용 데이터 추출
stds[stds['sci'] >= 85]

- 출력

array([('철수', 90, 85), ('돌이', 88, 92)],
      dtype=[('name', '<U10'), ('math', '<i4'), ('sci', '<i4')])

  1. 데이터 중 특정 요소 추출 (이름)
stds[stds['sci'] >= 85]['name']

- 출력

array(['철수', '돌이'], dtype='<U10')

3️⃣ 정렬

수학 점수 기준 정렬

np.sort(stds, order='math')

- 출력

array([('돌이', 88, 92), ('철수', 90, 85), ('영희', 95, 80)],
      dtype=[('name', '<U10'), ('math', '<i4'), ('sci', '<i4')])

4️⃣ 필드 추가

  • 기존 배열에 직접 추가는 불가하여 새로운 배열을 생성해야 한다.
  • np.empty 참조

새 배열 생성 및 평균(avg) 필드 추가

new_dtype = [('name', 'U10'), ('math', 'i4'), ('sci', 'i4'), ('avg', 'f4')]
new_stds = np.empty(len(stds), dtype=new_dtype)
new_stds

- 출력

array([('', 0, 0, 0.), ('', 0, 0, 0.), ('', 0, 0, 0.)],
      dtype=[('name', '<U10'), ('math', '<i4'), ('sci', '<i4'), ('avg', '<f4')])

  • 현재 빈 배열로 기존 배열의 데이터를 직접 추가해야 한다.
new_stds['name']

- 출력

array(['', '', ''], dtype='<U10')

  • 새 필드 avg 를 제외한 나머지 데이터를 입력하여 추가된 모습이다.
new_stds['name'] = stds['name']
new_stds['math'] = stds['math']
new_stds['sci'] = stds['sci']
new_stds

- 출력

array([('철수', 90, 85, 0.), ('영희', 95, 80, 0.), ('돌이', 88, 92, 0.)],
      dtype=[('name', '<U10'), ('math', '<i4'), ('sci', '<i4'), ('avg', '<f4')])

  • 새 필드 avg 도 추가한다.
new_stds['avg'] = (stds['math'] + stds['sci']) / 2
new_stds

- 출력

array([('철수', 90, 85, 87.5), ('영희', 95, 80, 87.5), ('돌이', 88, 92, 90. )],
      dtype=[('name', '<U10'), ('math', '<i4'), ('sci', '<i4'), ('avg', '<f4')])

5️⃣ 배열 파일 저장/로드

1) np.save()

np.save(파일이름, 배열명)

  • .npv 파일로 저장
np.save('students.npy', new_stds)

2) np.load()

np.load(npy파일이름, allow_pickle=True, ... )

std = np.load('students.npy')
std

- 출력

array([('철수', 90, 85, 87.5), ('영희', 95, 80, 87.5), ('돌이', 88, 92, 90. )],
      dtype=[('name', '<U10'), ('math', '<i4'), ('sci', '<i4'), ('avg', '<f4')])

6️⃣ 데이터프레임 변환

import pandas as pd

pd.DataFrame(new_stds)

- 출력

0개의 댓글