끄적끄적

2025.07.09 Pandas 실무 기초 세션 4 본문

[스파르타]내일배움캠프 데이터 분석 트랙/Session

2025.07.09 Pandas 실무 기초 세션 4

kminx 2025. 7. 9. 19:06
튜터 김연준 튜터님
학습 목표 1. concat()으로 여러 Series·DataFrame을 행/열 방향으로 병합하는 방법을 완전히 익힌다.
2. merge()의 다양한 조인 방식(left, right, inner, outer)을 통해 키 기준 데이터 병합을 실습한다.
3. groupby()와 집계 함수들로 그룹별 데이터 분석 및 cumsum()shift() 등 시계열 변환 기법을 활용한다.
4. rolling()과 expanding() 윈도우 함수로 이동평균, 누적통계량 계산을 통한 시계열 분석 기초를 이해한다.
더보기
목차
  1. Concat : 객체 합치기 심화
  2. Merge : 키 기준 데이터 병합
  3. Group : 그룹 기반 데이터 분석
  4. Expanding and Rolling : 윈도우 함수 활용

 

1️⃣ Concat : 객체 합치기 심화

  • pd.Series(): 1차원 배열 형태의 데이터를 담는 pandas 객체로, 리스트나 배열 등을 인덱스와 함께 열(column) 없이 생성할 때 사용
  • pd.DataFrame(): 2차원 표 형식의 데이터를 담는 pandas 객체로, 딕셔너리·리스트·넘파이 배열·다른 DataFrame 등을 기반으로 행과 열을 지정해 생성할 때 사용
  • concat(): 여러 Series나 DataFrame을 행(axis=0) 또는 열(axis=1) 방향으로 이어붙여 하나의 객체로 합칠 때 사용
import pandas as pd

# Series 기본 연결
s1 = pd.Series(['a', 'b'])
s2 = pd.Series(['c', 'd'])

# 기본 연결 (세로 방향)
pd.concat([s1, s2], ignore_index=True)

 

  • MultiIndex 생성: keys와 names 매개변수로 계층적 인덱스 구조 생성
# MultiIndex로 Series 연결
pd.concat([s1, s2], keys=['s1', 's2'], names=['Series name', 'Row ID'])

 

  • DataFrame 연결: 동일한 열 구조의 DataFrame들을 세로로 이어붙이기
Copydf1 = pd.DataFrame([['a', 1], ['b', 2]], columns=['letter', 'number'])
df2 = pd.DataFrame([['c', 3], ['d', 4]], columns=['letter', 'number'])
pd.concat([df1, df2])

 

  • 서로 다른 열 구조 처리: 누락된 열은 NaN 으로 자동 채우기
Copydf3 = pd.DataFrame([['c', 3, 'cat'], ['d', 4, 'dog']],
                   columns=['letter', 'number', 'animal'])

# 전체 열 유지 (sort=False로 열 순서 보존)
pd.concat([df1, df3], sort=False)

# 공통 열만 선택
pd.concat([df1, df3], join="inner")

 

 

2️⃣ Merge : 키 기준 데이터 병합

  • 조인 방식별 데이터 병합 : 관계형 데이터베이스의 JOIN과 유사한 방식으로 키 열 기준 병합
    • left: 왼쪽기준) DataFrame의 모든 행을 유지하면서 오른쪽과 키가 일치하는 행만 병합
    • right: 오른쪽(참조) DataFrame의 모든 행을 유지하면서 왼쪽과 키가 일치하는 행만 병합
    • inner: 양쪽 DataFrame에서 키가 일치하는 행만 병합하여 반환
    • outer: 양쪽 DataFrame의 모든 행을 유지하면서 키가 일치하지 않는 부분은 NaN으로 채워 병합
import pandas as pd

# 예제 데이터 생성
adf = pd.DataFrame({"x1": ["A", "B", "C"], "x2": [1, 2, 3]})
bdf = pd.DataFrame({"x1": ["A", "B", "D"], "x3": ["T", "F", "T"]})

# 다양한 조인 방식
pd.merge(adf, bdf, how='left', on='x1')    # 왼쪽 조인
pd.merge(adf, bdf, how='right', on='x1')   # 오른쪽 조인
pd.merge(adf, bdf, how='inner', on='x1')   # 내부 조인
pd.merge(adf, bdf, how='outer', on='x1')   # 외부 조인

 

  • 포함 여부 확인isin() 메서드로 특정 값들의 존재 여부 확인
# adf의 x1 열 값이 bdf의 x1 열에 포함되는지 확인
adf.x1.isin(bdf.x1)

# 포함되는 행만 선택
adf[adf.x1.isin(bdf.x1)]

# 포함되지 않는 행만 선택 (~는 NOT 연산자)
adf[~adf.x1.isin(bdf.x1)]

 

  • indicator 옵션: 병합 결과에 각 행의 출처 정보 추가
ydf = pd.DataFrame({"x1": ["A", "B", "C"], "x2": [1, 2, 3]})
zdf = pd.DataFrame({"x1": ["B", "C", "D"], "x2": [2, 3, 4]})

# 왼쪽에만 있는 데이터 추출
pd.merge(ydf, zdf, how='outer', indicator=True)\
    .query('_merge == "left_only"')\
    .drop(columns=['_merge'])

 

 

3️⃣ Group : 그룹 기반 데이터 분석

  • 누적 함수 : 시계열 데이터나 순서가 있는 데이터에서 누적 통계량을 계산
    • cumsum(): 시리즈나 DataFrame의 누적 합을 계산하여 동일한 형태로 반환
    • cummax(): 시리즈나 DataFrame의 누적 최대값을 계산하여 동일한 형태로 반환
    • cummin(): 시리즈나 DataFrame의 누적 최소값을 계산하여 동일한 형태로 반환
    • cumprod(): 시리즈나 DataFrame의 누적 곱을 계산하여 동일한 형태로 반환
import pandas as pd
import seaborn as sns

# mpg 데이터 로드
df = sns.load_dataset("mpg")

# 그룹별 집계
df.groupby(by="origin")['cylinders'].size()  # 그룹별 개수
df["origin"].value_counts()                   # 값별 빈도수

# 다중 그룹화
pd.DataFrame(df.groupby(['model_year', 'origin'])['cylinders'].mean())

 

  • 데이터 변환 함수 : 행별 데이터 변환 및 순위 계산
# 예제 DataFrame
df2 = pd.DataFrame([[4, 7, 10], [5, 11, 8], [6, 9, 12]],
                   index=[1, 2, 3], columns=['a', 'b', 'c'])

# 데이터 이동 (shift)
df2['b'].shift(2)  # 2행 아래로 이동, 앞부분은 NaN

# 순위 계산
df["model_year"].rank(method='first').head()

# 누적 통계량들
df2.cumsum()   # 누적 합계
df2.cummax()   # 누적 최대값
df2.cummin()   # 누적 최소값
df2.cumprod()  # 누적 곱

 

 

4️⃣ Expanding and Rolling: 윈도우 함수 활용

  • 윈도우 함수 개념 : 시계열 데이터의 부분집합에 함수를 적용하여 평활화나 추세 분석 수행
    • Expanding: 최소 관측치 개수 이상부터 첫 관측 시점부터 현재 시점까지의 모든 데이터를 누적하여 함수를 적용하는 누적 윈도우 기법
    • Rolling: 고정된 길이(window)를 현재 시점을 포함한 과거 구간만큼 슬라이딩하며 함수를 적용하는 이동 윈도우 기법
    • 이동평균 : 일정 기간(window) 내 값들의 평균을 계산하여 시계열을 평활화하는 통계적 방법
import pandas as pd
import numpy as np
import matplotlib.pyplot as plt

# 시계열 데이터 생성
s = pd.Series(np.random.randn(1000),
              index=pd.date_range('1/1/2015', periods=1000))
s = s.cumsum()

# 이동 윈도우 (Rolling)
r = s.rolling(window=30)  # 30일 이동 윈도우
rolling_mean = r.mean()   # 30일 이동평균

# 시각화
s.plot(style='k--', label='Original')
rolling_mean.plot(style='k', label='30-day Rolling Mean')
plt.legend()

 

  • 다변량 데이터 윈도우 분석 : 여러 열에 대한 동시 윈도우 함수 적용
# 다변량 시계열 데이터
df = pd.DataFrame(np.random.randn(1000, 4),
                  index=pd.date_range('1/1/2015', periods=1000),
                  columns=['A', 'B', 'C', 'D'])
df = df.cumsum()

# 60일 이동 합계를 각 열별 서브플롯으로 시각화
df.rolling(window=60).sum().plot(subplots=True)

 

  • 확장 윈도우 (Expanding) : 처음부터 현재까지 모든 데이터 포함
    • 윈도우 함수 매개변수 : min_periods로 최소 관측치 개수 조절하여 결측값 처리 최적화
# 누적 평균 계산 및 시각화
df.expanding(min_periods=1).mean().plot()

# 최소 관측치 개수 설정 예제
dfe = pd.DataFrame({'B': [0, 1, 2, np.nan, 4]})

# 최소 2개 관측치부터 확장 윈도우 적용
dfe.expanding(2).mean().plot()

 

 

 


2025.07.08 - [[스파르타]내일배움캠프 데이터 분석 트랙] - 36일차 - 실무에서 필요한 Pandas 기초 1

 

2025.07.02 Pandas 실무 기초 세션 1

튜터김연준 튜터님학습 목표1. Pandas의 기본 데이터 구조 Series, DataFrame을 명확히 이해한다.2. 결측치 개념인 NaN과 Null의 차이를 파악하고 적절히 처리한다.3. 비교 연산자/논리 연산자/조건 필터링

kminx.tistory.com

2025.07.08 - [[스파르타]내일배움캠프 데이터 분석 트랙/Session] - 2025.07.04 Pandas 실무 기초 세션 2

 

2025.07.04 Pandas 실무 기초 세션 2

튜터김연준 튜터님학습 목표1. DataFrame에서 원하는 열(column)만 손쉽게 추출하는 방법을 익힌다.2. value_counts(), unique(), describe() 외에도 기초 통계 함수(sum(), count(), nunique() 등)를 활용해 데이터 특성

kminx.tistory.com

2025.07.08 - [[스파르타]내일배움캠프 데이터 분석 트랙/Session] - 2025.07.07 Pandas 실무 기초 세션 3

 

2025.07.07 Pandas 실무 기초 세션 3

튜터김연준 튜터님학습 목표1. 결측치가 포함된 데이터를 dropna() 와 fillna() 로 효과적으로 처리하는 방법을 익힌다.2. assign(), qcut(), lambda 함수를 활용해 메서드 체이닝으로 새로운 열을 추가·변

kminx.tistory.com