
데이터 분석을 위한 Python 라이브러리 중 가장 널리 사용되는 것은 단연 Pandas입니다. Pandas는 구조화된 데이터를 효율적으로 처리할 수 있는 강력한 도구입니다. 오늘은 Pandas의 가장 기본적인 데이터 구조인 Series 객체에 대해 자세히 알아보겠습니다.
Pandas Series란?
Pandas Series는 1차원 데이터 구조로, NumPy 배열과 유사하지만 각 데이터에 레이블(인덱스)을 부여할 수 있다는 중요한 차이점이 있습니다. 이는 데이터를 더 직관적으로 접근하고 조작할 수 있게 해줍니다.
Series의 주요 특징:
- 인덱스 레이블을 가진 1차원 배열
- 다양한 데이터 타입 지원 (숫자, 문자열, 객체 등)
- NumPy 배열 연산 지원
- 결측치(NaN) 처리 기능
먼저 Pandas를 임포트하는 것부터 시작하겠습니다:
import pandas as pd
Series 생성하기
Series를 생성하는 가장 기본적인 방법은 리스트를 Pandas의 Series 생성자에 전달하는 것입니다:
# 기본 Series 생성
s = pd.Series([0.0, 3.6, 2.0, 5.8, 4.2, 8.0])
print(s)
# 0 0.0
# 1 3.6
# 2 2.0
# 3 5.8
# 4 4.2
# 5 8.0
# dtype: float64
출력 결과에서 볼 수 있듯이, Series는 인덱스(왼쪽)와 값(오른쪽)의 쌍으로 구성됩니다. 기본적으로 인덱스는 0부터 시작하는 정수입니다.
인덱스 설정 및 변경
Series의 강력한 기능 중 하나는 사용자 정의 인덱스를 설정할 수 있다는 것입니다. 인덱스를 변경하면 데이터에 접근하는 방식이 더 직관적이 될 수 있습니다.
# 인덱스 변경
s.index = pd.Series([0.0, 1.2, 1.8, 3.0, 3.6, 4.8])
s.index.name = 'MY_IDX' # 인덱스에 이름 부여
print(s)
# MY_IDX
# 0.0 0.0
# 1.2 3.6
# 1.8 2.0
# 3.0 5.8
# 3.6 4.2
# 4.8 8.0
# dtype: float64
인덱스에 이름을 부여하면 데이터의 의미를 더 명확히 할 수 있습니다. 마찬가지로, Series 자체에도 이름을 부여할 수 있습니다:
# Series에 이름 부여
s.name = 'MY_SERIES'
print(s)
# MY_IDX
# 0.0 0.0
# 1.2 3.6
# 1.8 2.0
# 3.0 5.8
# 3.6 4.2
# 4.8 8.0
# Name: MY_SERIES, dtype: float64
데이터 추가 및 변경
Series는 동적으로 데이터를 추가하거나 변경할 수 있습니다. 새로운 인덱스와 값을 지정하여 데이터를 추가할 수 있습니다:
# 단일 데이터 추가
s[5.9] = 5.5
print(s)
# MY_IDX
# 0.0 0.0
# 1.2 3.6
# 1.8 2.0
# 3.0 5.8
# 3.6 4.2
# 4.8 8.0
# 5.9 5.5
# Name: MY_SERIES, dtype: float64
또한, append()
메서드를 사용하여 다른 Series의 데이터를 추가할 수도 있습니다:
# 다른 Series 데이터 추가
ser = pd.Series([6.7, 4.2], index=[6.8, 8.0])
s = s.append(ser)
print(s)
# 0.0 0.0
# 1.2 3.6
# 1.8 2.0
# 3.0 5.8
# 3.6 4.2
# 4.8 8.0
# 5.9 5.5
# 6.8 6.7
# 8.0 4.2
# dtype: float64
참고: Pandas 1.4.0 버전부터 append()
메서드는 deprecated되었으며, 대신 pd.concat()
함수를 사용하는 것이 권장됩니다:
# 최신 방식으로 Series 연결하기
s = pd.concat([s, ser])
데이터 접근 방법
Series의 데이터에 접근하는 방법은 여러 가지가 있습니다. 가장 일반적인 방법들을 살펴보겠습니다:
인덱스를 통한 접근
# 인덱스 레이블로 접근
print(s.loc[8.0]) # 4.2
위치를 통한 접근
# 정수 위치로 접근 (0부터 시작)
print(s.iloc[-1]) # 4.2 (마지막 요소)
NumPy 스타일 접근
# 마지막 인덱스 값 확인
print(s.index[-1]) # 8.0
# 마지막 데이터 값 확인
print(s.values[-1]) # 4.2
# values 속성으로 NumPy 배열 접근
print(s.values[:]) # [0. 3.6 2. 5.8 4.2 8. 5.5 6.7 4.2]
슬라이싱
Series는 Python의 슬라이싱 문법을 지원합니다:
# iloc을 이용한 위치 기반 슬라이싱
print(s.iloc[:]) # 전체 Series 반환
# 0.0 0.0
# 1.2 3.6
# 1.8 2.0
# 3.0 5.8
# 3.6 4.2
# 4.8 8.0
# 5.9 5.5
# 6.8 6.7
# 8.0 4.2
# dtype: float64
데이터 삭제
drop()
메서드를 사용하여 특정 인덱스의 데이터를 삭제할 수 있습니다:
# 특정 인덱스 데이터 삭제
print(s.drop(8.0))
# 0.0 0.0
# 1.2 3.6
# 1.8 2.0
# 3.0 5.8
# 3.6 4.2
# 4.8 8.0
# 5.9 5.5
# 6.8 6.7
# dtype: float64
주의할 점은 drop()
메서드는 원본 Series를 변경하지 않고 변경된 새로운 Series를 반환한다는 것입니다. 원본을 변경하려면 inplace=True
매개변수를 사용해야 합니다:
s.drop(8.0, inplace=True) # 원본 Series 변경
기술 통계량 계산
Pandas Series는 데이터의 기술 통계량을 쉽게 계산할 수 있는 describe()
메서드를 제공합니다:
print(s.describe())
# count 9.000000 원소 개수
# mean 4.444444 평균
# std 2.430078 표준편차
# min 0.000000 최솟값
# 25% 3.600000 제1 사분위수
# 50% 4.200000 제2 사분위수
# 75% 5.800000 제3 사분위수
# max 8.000000 최댓값
# dtype: float64
이 메서드는 데이터의 기본적인 통계 정보를 한눈에 볼 수 있게 해줍니다. 특히 대용량 데이터를 다룰 때 데이터의 특성을 빠르게 파악하는 데 유용합니다.
Series 시각화하기
Pandas는 Matplotlib과 통합되어 Series 데이터를 쉽게 시각화할 수 있습니다:
import pandas as pd
import matplotlib.pyplot as plt
# Series 생성 및 설정
s = pd.Series([0.0, 3.6, 2.0, 5.8, 4.2, 8.0, 5.5, 6.7, 4.2])
s.index = pd.Index([0.0, 1.2, 1.8, 3.0, 3.6, 4.8, 5.9, 6.8, 8.0])
s.index.name = 'MY_IDX'
s.name = 'MY_SERIES'
# 그래프 그리기
plt.title('ELLIOTT_WAVE')
plt.plot(s, 'bs--') # 파란색 사각형 마커와 점선
plt.xticks(s.index) # x축 눈금을 인덱스 값으로 설정
plt.yticks(s.values) # y축 눈금을 데이터 값으로 설정
plt.grid(True) # 그리드 표시
plt.show()
이 코드는 다음과 같은 그래프를 생성합니다:
- 파란색 사각형 마커와 점선으로 Series 데이터를 표시
- x축에는 Series의 인덱스 값이 표시됨
- y축에는 Series의 데이터 값이 표시됨
- 그리드가 표시되어 값을 쉽게 읽을 수 있음
Series의 실용적 활용 예시
이제 Series의 기본 개념을 이해했으니, 몇 가지 실용적인 활용 예시를 살펴보겠습니다:
시계열 데이터 분석
# 날짜 인덱스를 가진 Series 생성
dates = pd.date_range('20240101', periods=6)
time_series = pd.Series(range(6), index=dates)
print(time_series)
# 2024-01-01 0
# 2024-01-02 1
# 2024-01-03 2
# 2024-01-04 3
# 2024-01-05 4
# 2024-01-06 5
# Freq: D, dtype: int64
# 주별 리샘플링
weekly = time_series.resample('W').sum()
print(weekly)
# 2024-01-07 15
# Freq: W-SUN, dtype: int64
데이터 필터링
# 조건에 맞는 데이터 필터링
filtered = s[s > 4.0]
print(filtered)
# 3.0 5.8
# 3.6 4.2
# 4.8 8.0
# 5.9 5.5
# 6.8 6.7
# 8.0 4.2
# dtype: float64
데이터 변환
# 데이터 변환 (각 값의 제곱)
squared = s.apply(lambda x: x**2)
print(squared)
# 0.0 0.00
# 1.2 12.96
# 1.8 4.00
# 3.0 33.64
# 3.6 17.64
# 4.8 64.00
# 5.9 30.25
# 6.8 44.89
# 8.0 17.64
# dtype: float64
Series vs DataFrame
Pandas의 두 가지 주요 데이터 구조인 Series와 DataFrame의 차이점을 간략히 정리해 보겠습니다:
특성 | Series | DataFrame |
---|---|---|
차원 | 1차원 | 2차원 |
구조 | 인덱스-값 쌍 | 행과 열 구조 |
인덱스 | 단일 인덱스 | 행 인덱스와 열 이름 |
데이터 접근 | s[idx], s.iloc[pos] | df[col], df.loc[row, col] |
유사한 구조 | Python 딕셔너리, NumPy 배열 | Excel 스프레드시트, SQL 테이블 |
Series는 DataFrame의 기본 구성 요소입니다. DataFrame의 각 열은 Series 객체입니다.
# Series를 이용한 DataFrame 생성
s1 = pd.Series([1, 2, 3], index=['a', 'b', 'c'])
s2 = pd.Series([4, 5, 6], index=['a', 'b', 'c'])
df = pd.DataFrame({'col1': s1, 'col2': s2})
print(df)
# col1 col2
# a 1 4
# b 2 5
# c 3 6
마치며
Pandas Series는 데이터 분석 작업의 기초가 되는 강력한 도구입니다. 이 포스트에서는 Series의 생성, 인덱싱, 데이터 조작, 통계 분석, 시각화 등의 기본 기능을 살펴보았습니다.
Series의 장점을 요약하면 다음과 같습니다:
- 명시적인 인덱스를 통한 직관적인 데이터 접근
- 내장된 통계 및 수학 함수
- 손쉬운 데이터 시각화
- 결측치 처리 기능
- NumPy와의 완벽한 호환성
Pandas Series를 통해 데이터를 효과적으로 분석하고, 이를 바탕으로 더 복잡한 데이터 구조인 DataFrame을 다루는 기초를 마련하시기 바랍니다.
다음 포스트에서는 Pandas DataFrame에 대해 더 자세히 알아보겠습니다.