Pandas - 4. 데이터 선택 및 필터링

2025. 2. 4. 11:31프로그래밍 (확장)/Python-Pandas

Pandas에서 데이터를 선택하고 필터링하는 방법은 데이터 분석의 핵심 요소입니다. 이 문서에서는 iloc, loc, at, iat 등의 기본적인 데이터 선택 방법부터 조건부 필터링, 고급 인덱싱, 대용량 데이터 처리까지 초보자가 이해하기 쉽게 설명하고 예제를 포함하였습니다.


1. 샘플 데이터 준비

이 문서의 모든 예제에서 사용할 일관된 데이터프레임을 생성합니다.

import pandas as pd

# 샘플 데이터 생성
data = {
    '이름': ['철수', '영희', '민수', '지연', '현우'],
    '나이': [25, 30, 22, 27, 35],
    '도시': ['서울', '부산', '대구', '광주', '서울'],
    '점수': [90, 85, 88, 76, 95]
}
df = pd.DataFrame(data)
print(df)

출력:

   이름  나이   도시  점수
0  철수  25  서울  90
1  영희  30  부산  85
2  민수  22  대구  88
3  지연  27  광주  76
4  현우  35  서울  95

2. 기본 데이터 선택

2.1 iloc (정수 기반 인덱싱)

# 특정 행 선택 (0번째 행)
print(df.iloc[0])

# 특정 행과 열 선택 (0번째 행, 2번째 열)
print(df.iloc[0, 2])

출력:

이름      철수
나이      25
도시      서울
점수      90
Name: 0, dtype: object

서울

2.2 loc (레이블 기반 인덱싱)

# 특정 행 선택
print(df.loc[0])

# 특정 행과 열 선택
print(df.loc[0, '도시'])

출력:

이름      철수
나이      25
도시      서울
점수      90
Name: 0, dtype: object

서울

2.3 at (단일 값 접근 최적화)

print(df.at[1, '이름'])

출력:

영희

2.4 iat (정수 인덱스를 이용한 단일 값 접근 최적화)

print(df.iat[1, 0])

출력:

영희

⚠️ 주의:

  • at, iat는 단일 값 접근에 최적화되어 있지만, 여러 값을 선택할 때는 loc, iloc을 사용하는 것이 좋습니다.
  • 잘못된 인덱스를 참조하면 KeyError 또는 IndexError가 발생할 수 있습니다.

3. 조건부 필터링

3.1 단일 조건 필터링

# 나이가 25 이상인 데이터 선택
filtered_df = df[df['나이'] >= 25]
print(filtered_df)

3.2 여러 조건 결합 (AND, OR)

# AND 조건: 나이가 25 이상이고 도시가 '서울'인 데이터 선택
filtered_df = df[(df['나이'] >= 25) & (df['도시'] == '서울')]
print(filtered_df)
# OR 조건: 나이가 25 이상이거나 도시가 '부산'인 데이터 선택
filtered_df = df[(df['나이'] >= 25) | (df['도시'] == '부산')]
print(filtered_df)

출력:

   이름  나이   도시  점수
0  철수  25  서울  90
1  영희  30  부산  85
3  지연  27  광주  76
4  현우  35  서울  95

4. 고급 인덱싱 및 추가 기능

4.1 불리언 인덱싱 (Boolean Indexing)

⚠️ 주의: 불리언 조건을 사용할 때 반드시 각 조건을 괄호로 감싸야 합니다.

# 잘못된 예: df[df.A > 0 & df.B > 0]  # 에러 발생
# 올바른 예:
df[(df.A > 0) & (df.B > 0)]

4.2 query() 메서드 사용법

# 나이가 25 이상인 행 선택
print(df.query('나이 >= 25'))

# 나이가 25 이상이고 도시가 '서울'인 행 선택
print(df.query("나이 >= 25 and 도시 == '서울'"))

출력:

   이름  나이   도시  점수
0  철수  25  서울  90
1  영희  30  부산  85
3  지연  27  광주  76
4  현우  35  서울  95

   이름  나이   도시  점수
0  철수  25  서울  90
4  현우  35  서울  95

4.3 슬라이싱 (Slicing)

# 1번째부터 3번째 행까지 선택
print(df[1:3])

# 특정 열 범위 선택
print(df.loc[:, '이름':'도시'])

출력:

   이름  나이   도시  점수
1  영희  30  부산  85
2  민수  22  대구  88

   이름  나이   도시
0  철수  25  서울
1  영희  30  부산
2  민수  22  대구
3  지연  27  광주
4  현우  35  서울

4.4 인덱스 재설정 (Reset Index)

# 인덱스 초기화
df_reset = df.reset_index(drop=True)
print(df_reset)

5. 성능 고려사항 및 대용량 데이터 처리

방법 속도  사용 추천
iloc 보통 여러 행/열 선택 시
loc 보통 레이블을 사용한 선택
at 빠름 단일 값 접근
iat 매우 빠름 단일 값 접근 (정수 인덱스)

5.1 대용량 데이터 처리 Best Practice

query() 메서드 성능 특성

query() 메서드는 벡터 연산을 활용하여 필터링 속도가 빠르며, 대용량 데이터셋에서 df[df['컬럼'] 조건]보다 성능이 향상될 수 있습니다.

  • query()는 내부적으로 Pandas의 NumPy 기반 연산을 사용하여 필터링 속도를 개선합니다.
  • 문자열 조건을 사용할 때 성능이 좋으며, 다중 조건 필터링에서 가독성이 높습니다.
  • 단점: query() 내부에서 변수 사용 시 @변수명 형태로 지정해야 합니다.

예제: query() 성능 비교

import time

large_df = pd.DataFrame({'A': range(1000000), 'B': range(1000000, 2000000)})

# df[df['A'] > 500000] 방식
start = time.time()
filtered_df = large_df[large_df['A'] > 500000]
print(f"df[df['A'] > 500000] 실행 시간: {time.time() - start:.5f}초")

# query() 방식
start = time.time()
filtered_df = large_df.query('A > 500000')
print(f"query('A > 500000') 실행 시간: {time.time() - start:.5f}초")

1. chunksize를 이용한 부분 로딩

# 대용량 CSV 파일을 청크 단위로 로드하여 처리
chunk_size = 10000  # 10,000행씩 로드
for chunk in pd.read_csv('large_file.csv', chunksize=chunk_size):
    print(chunk.head())

2. 메모리 절약을 위한 데이터 타입 변환

데이터 타입 변환을 통해 메모리 사용량을 줄일 수 있습니다.

# 변환 전 메모리 사용량 확인
print(f"변환 전 메모리 사용량: {df.memory_usage(deep=True).sum()} bytes")

# 정수형 데이터 타입을 다운캐스팅하여 메모리 절약
df['나이'] = pd.to_numeric(df['나이'], downcast='integer')

# 변환 후 메모리 사용량 확인
print(f"변환 후 메모리 사용량: {df.memory_usage(deep=True).sum()} bytes")
# 정수형 데이터 타입을 다운캐스팅하여 메모리 절약
df['나이'] = pd.to_numeric(df['나이'], downcast='integer')

3. query()를 사용한 빠른 데이터 필터링

# 큰 데이터셋에서 query()는 불필요한 인덱싱을 줄여 성능 향상 가능
df_filtered = df.query('나이 > 25 and 점수 >= 80')

6. 요약 및 실제 사용 사례

  • iloc, loc, at, iat의 차이점을 이해하고 적절히 사용할 수 있습니다.
  • 필터링을 활용하여 데이터를 효과적으로 추출할 수 있습니다.
  • 대량의 데이터를 다룰 때는 성능 최적화를 고려하여 적절한 선택 방법을 사용합니다.

'프로그래밍 (확장) > Python-Pandas' 카테고리의 다른 글

Pandas - 6. 데이터 연산  (0) 2025.02.08
Pandas - 5. 데이터 전처리  (0) 2025.02.04
Pandas - 3. 데이터 입출력 (I/O)  (0) 2025.01.24
Pandas - 2. 데이터 구조  (0) 2025.01.24
Pandas - 1. 소개와 설치  (0) 2025.01.24