ABC부트캠프

[6일차] 간단한 데이터 집계와 데이터 처리 심화

수야! 2025. 7. 2. 23:20

[Python 데이터 전처리 기초]

-기초 문법부터 데이터 결합 및 파생 변수 생성까지

 

<목차>

#01. 데이터 분석의 이해

#02. Python 기초 문법

#03. 데이터 처리 기초

#04. 간단한 데이터 집계 및 시각화

#05. 데이터 처리 심화

#06. 프로젝트 실습

 

<지난 시간 복습>

 

1. 데이터 결합

기능 함수 & 문법 설명
여러 파일 연결 pd.concat([df1, df2, …], axis=0|1, ignore_index=True) 동일한 컬럼 구조의 DataFrame을 행(axis=0) 또는 열(axis=1) 방향으로 이어 붙임. ignore_index=True로 새 인덱스 부여.
인덱스 초기화 df.reset_index(drop=True, inplace=True) 중복·불규칙해진 인덱스를 0부터 다시 순차적으로 부여. drop=True로 기존 인덱스 버림.
키(key) 결합 pd.merge(left, right, how='inner'|'left'|'right'|'outer', on='key') SQL JOIN 또는 VLOOKUP처럼, 공통 키 기준으로 두 DataFrame을 합침.
 

2. 변수(열) 선택

기능 문법 설명
속성 접근 df.col 공백·특수문자 없는 열만 간단 호출 → Series 반환
인덱싱 df['col'], df[['c1','c2',…]] 모든 이름의 열 선택 가능 → 단일 열은 Series, 복수 열은 DataFrame 반환
정규표현식 필터링 df.filter(regex='^s' | 's$') 컬럼 이름이 특정 패턴(시작/끝)과 일치하는 열만 골라냄
자료형별 선택 df.select_dtypes(include='number'|'object') 수치형(정수/실수)·문자형(object) 등 원하는 타입의 열만 선택

3. 행(관측치) 선택

기능 문법 설명
번호 슬라이스 df[start:stop] 0-based 행 인덱스 start…stop-1 선택
레이블 기반 접근 df.loc[row_label, col_label], df.loc['a':'c', ['c1','c2']] 인덱스 이름·열 이름으로 선택, 슬라이스는 끝 레이블 포함
위치 기반 접근 df.iloc[i,j], df.iloc[0:2, 1:3] 정수 위치(0-based)로 선택, 슬라이스는 끝 위치 미포함
불리언 마스킹 df[df['col']<x], df.loc[(cond1)&(cond2)] 조건식 → True인 행만 필터링
목록 포함 여부 df[df['col'].isin([...])] 컬럼 값이 특정 목록에 포함된 행만 선택
문자열 패턴 df[df['strcol'].str.startswith('b')], .contains(…), .endswith(…) 문자열 컬럼에서 패턴 매칭
범위 선택 df[df['num'].between(lo, hi, inclusive=…)] 수치형 컬럼의 특정 구간(lo ≤ x ≤ hi 등) 행 선택
 

4. 일부 관측치 추출

기능 문법 설명
첫/끝 확인 df.head(n), df.tail(n) 상위/하위 n개 행을 빠르게 확인
랜덤 샘플 df.sample(n) 또는 df.sample(frac) 무작위로 n개 행 또는 전체에서 frac 비율만큼 샘플링
상위/하위 극값 df.nlargest(n, 'col'), df.nsmallest(n, 'col') 지정 컬럼값이 큰/작은 상위 n개(또는 하위 n개) 행을 반환

데이터 집계

주요 내용

  1. 건수, 합계 평균 등 집계값 계산
  2. 정렬 및 피벗테이블 활용

목표

  1. 집계값을 계산할 수 있다.
  2. 피벗 테이블 등 다양한 방법으로 집계하고, 결과값을 적절히 정렬할 수 있다.

이번시간에는 데이터 집계만 다루고 시각화는 다음시간에 배울 예정입니다!

 

1. 수치형 변수의 집계값과 히스토그램

하나의 수치형 변수로 합계, 평균과 같은 집계값을 계산할 수 있고 히스토그램으로 분포를 확인할 수 있습니다.

 

1.1. 수치형 변수의 집계값 계산

<DataFrame: 보험료 데이터 일부>

df_ins = pd.DataFrame({
    'age':     [22, 35, 28, 41, 30],
    'charges': [2300, 4500, 3200, 7800, 4100]
})

 

1.1.1. sum()

  • 설명
    수치형 Series의 모든 값을 더한 합계를 계산합니다.
total_charges = df_ins['charges'].sum()
print("총 보험료 합계:", total_charges)

#출력결과
총 보험료 합계: 22900

 

1.1.2. mean()

  • 설명
    수치형 Series의 산술 평균을 계산합니다.
mean_age = df_ins['age'].mean()
print("평균 나이:", mean_age)

#출력결과
평균 나이: 31.2

 

1.1.3. max()

  • 설명
    수치형 Series에서 가장 큰 최대값을 반환합니다.
max_charge = df_ins['charges'].max()
print("최대 보험료:", max_charge)

#출력결과
최대 보험료: 7800

 

1.1.4. min()

  • 설명
    수치형 Series에서 가장 작은 최소값을 반환합니다.
min_charge = df_ins['charges'].min()
print("최소 보험료:", min_charge)

#출력결과
최소 보험료: 2300

 

1.1.5. var()

  • 설명
    수치형 Series의 **분산(Variance)**을 계산합니다.
    • 판다스는 기본적으로 표본 분산(자유도 ddof=1)을 반환합니다.
var_charges = df_ins['charges'].var()
print("charges 분산:", var_charges)

#출력결과
charges 분산: 4509500.0

 

1.1.6. std()

  • 설명
    수치형 Series의 **표준편차(Standard Deviation)**를 계산합니다.
std_charge = df_ins['charges'].std()
print("보험료 표준편차:", std_charge)

#출력결과
보험료 표준편차: 2089.864629541589

 

1.1.7. count()

  • 설명
    수치형 Series에서 NaN이 아닌(유효한) 값의 개수를 반환합니다.
count_charges = df_ins['charges'].count()
print("charges 개수:", count_charges)

#출력결과
charges 개수: 5

 

1.1.8. describe()

  • 설명
    수치형 Series에 대해 count, mean, std, min, 25%/50%/75% quantile, max 를 한 번에 요약해서 보여줍니다.
summary = df_ins['charges'].describe()
print("요약 통계량:\n", summary)

#출력결과
요약 통계량:
count       5.000000
mean     4580.000000
std      2089.864630
min      2300.000000
25%      3200.000000
50%      4100.000000
75%      4500.000000
max      7800.000000
Name: charges, dtype: float64

 

1.1.8. axis 인자를 통해 계산

  • axis=0 (기본값): 행 방향으로 이동하면서 열별 합계를 계산
  • axis=1 : 열 방향으로 이동하면서 행별 합계를 계산
import pandas as pd

# 예시 DataFrame: 두 개의 수치형 변수
df = pd.DataFrame({
    'A': [1, 2, 3],
    'B': [10, 20, 30],
    'C': ['x','y','z']    # 비수치형 열은 자동 무시됨
})
print(df)

#출력결과
   A   B  C
0  1  10  x
1  2  20  y
2  3  30  z

 

-기본 sum() (열별 합계, axis=0)

col_sums = df.sum()
print(col_sums)

#출력결과
A     6    # 1+2+3
B    60    # 10+20+30
C     xyz  # 문자열은 문자열끼리 이어 붙여짐
dtype: object

 

-sum(axis=1) (행별 합계)

row_sums = df.sum(axis=1)
print(row_sums)

#출력결과
0    11    # 1 + 10
1    22    # 2 + 20
2    33    # 3 + 30
dtype: int64

 

2. 그룹별 집계값의 계산과 분포 비교

범주형 변수를 그룹처럼 활용해서 그룹별 평균을 계산하고, 그룹별 상자그림을 그려서 그룹간 분포를 비교
한 변수의 집계에서 groupby()를 추가하면 되고, 필요에 따라 agg()를 활용이 가능합니다.

 

그룹별 평균 계산 (Series 반환)

  • 함수 조합: groupby() + mean()
  • 역할: 범주형 컬럼을 기준으로 그룹화한 뒤, 각 그룹의 수치형 값 평균을 계산하여 Series 형태로 반환합니다.
# 전체 평균 계산
df_ins['charges'].mean()

# 그룹별 평균 계산
# df_ins['sex'].unique()
df_ins.groupby('sex')['charges'].mean()

# 그룹별 평균 계산(DataFrame 형식으로 출력)
df_ins.groupby('sex', as_index=False)['charges'].mean()

 

2.1 다양한 그룹 집계값의 계산 예제

2.1.1. 여러 개의 그룹 변수로 계산

: 둘 이상의 범주형 컬럼을 함 께 그룹 키로 사용하여, 각 그룹별 수치형 변수를 계산합니다.

df.groupby(
    [함수1, 함수2],      # 그룹화에 사용할 복수의 범주형 컬럼
    as_index=False      # 결과를 인덱스가 아닌 컬럼으로 유지
)[집계대상컬럼].집계함수()  # numeric 컬럼에 대해 적용할 집계함수

 

 

<예제>

import pandas as pd

# 예시 DataFrame
df = pd.DataFrame({
    'sex':    ['F','F','M','M','F','M'],
    'smoker': ['Y','N','Y','N','Y','N'],
    'charges':[200,150,300,250,180,220]
})

result = df.groupby(['sex','smoker'], as_index=False)['charges'].mean()
print(result)

#출력결과
  sex smoker  charges
0   F      N    150.0
1   F      Y    190.0
2   M      N    235.0
3   M      Y    300.0

 

2.1.2. 그룹별 여러 변수의 계산

: 한 개의 그룹 키를 기준으로, 두 개 이상의 수치형 컬럼을 동시에 계산합니다.

df.groupby(
    [그룹키컬럼],            # 함수1: 그룹화할 단일 컬럼 이름
    as_index=False         # 결과를 인덱스가 아닌 컬럼으로 유지
)[
    [집계대상컬럼1, 집계대상컬럼2]  # numeric 컬럼을 리스트로 지정
].집계함수()               # .mean(), .sum(), .count(), .max(), .min() 등

 

<예제>

df = pd.DataFrame({
    'sex':    ['F','F','M','M'],
    'age':    [25, 30, 35, 40],
    'charges':[200,150,300,250]
})

result = df.groupby('sex', as_index=False)[['age','charges']].mean()
print(result)

#출력결과
  sex   age  charges
0   F  27.5    175.0
1   M  37.5    275.0

 

2.1.3. 그룹별 한 변수의 여러 집계 함수 적용 (agg with list)

: 한 개의 그룹 키, 한 개의 수치형 컬럼에 대해 여러 통계 함수(min,max,mean 등)를 한 번에 계산합니다.

df.groupby(
    [그룹키컬럼],          # 그룹화할 컬럼 이름
    as_index=False       # 결과를 DataFrame으로 유지
)['집계대상컬럼'].agg(    # numeric 컬럼 하나 선택
    [최소함수, 최대함수, 평균함수]  # 예: ['min','max','mean']
)

 

 

<예제>

df = pd.DataFrame({
    'sex':    ['F','F','M','M'],
    'charges':[200,150,300,250]
})

stats = df.groupby('sex', as_index=False)['charges'].agg(['min','max','mean'])
print(stats)

#출력결과
       min  max   mean
sex                     
F      150  200  175.0
M      250  300  275.0

 

2.1.4. 일반적인 그룹별 집계 (딕셔너리 agg)

: 그룹 키 하나에 대해 여러 컬럼을 각각 여러 함수로 집계할 때, dict 형태로 함수 매핑을 지정합니다.

df.groupby(
    [그룹키컬럼],       # 그룹화할 범주형 컬럼 (문자열 또는 리스트)
    as_index=False     # 결과를 DataFrame으로 유지
).agg({               # 컬럼별로 적용할 집계함수들을 딕셔너리로 지정
    '집계대상컬럼1': [집계함수A, ...],  # 예: ['mean']
    '집계대상컬럼2': [집계함수B, 집계함수C, ...]  # 예: ['min','max']
})

 

<예제>

df = pd.DataFrame({
    'sex':    ['F','F','M','M'],
    'age':    [25, 30, 35, 40],
    'charges':[200,150,300,250]
})

df_agg = df.groupby('sex', as_index=False) \
           .agg({'age':'mean','charges':['min','max']})
print(df_agg)

#출력결과
   sex   age charges      
         mean   min  max
0   F  27.5     150  200
1   M  37.5     250  300

 

2.1.5. MultiIndex 컬럼 선택

: agg 결과가 다중 레벨 컬럼(MultiIndex)일 때, 튜플(('charges','min'))을 이용해 특정 집계값만 선택합니다.

df_agg[(집계대상컬럼, 집계함수명)]

 

<예제>

# 위 df_agg 결과에서 'charges'의 'min'값만 꺼내기
mins = df_agg[('charges','min')]
print(mins)

#출력결과
0    150
1    250
Name: (charges, min), dtype: int64

 

 

3. 데이터 집계와 데이터 처리

3.1. groupby('region')['charges'].mean()

정의
: 'region'별로 그룹화한 뒤, 각 그룹의 'charges' 평균을 계산하여 Series로 반환합니다.

df.groupby('region')['charges'].mean()

 

<예제 코드>

import pandas as pd

df = pd.DataFrame({
    'region': ['A', 'B', 'A', 'C', 'B'],
    'charges': [100, 200, 300, 150, 250]
})

avg_by_region = df.groupby('region')['charges'].mean()
print(avg_by_region)

#출력결과
region
A    200.0
B    225.0
C    150.0
Name: charges, dtype: float64

 

3.2. nlargest(2, 'charges')

정의
: 지정한 컬럼(charges)을 기준으로 상위 2개(n=2)의 을 DataFrame 형태로 반환합니다.

df.nlargest(n, '컬럼명')

 

<예제 코드>

import pandas as pd

df_agg = pd.DataFrame({
    'region': ['A', 'B', 'C', 'D'],
    'charges': [200, 450, 300, 400]
})

top2 = df_agg.nlargest(2, 'charges')
print(top2)

#출력결과
  region  charges
1      B      450
3      D      400

 

3.3.isin(targets)

정의
: 원본 Series의 각 값이 주어진 리스트(targets)에 포함되어 있는지 여부를 Boolean Series로 반환합니다.

df['컬럼명'].isin(리스트_또는_시퀀스)

 

<예제 코드>

import pandas as pd

df = pd.DataFrame({
    'region': ['A', 'B', 'C', 'A', 'D'],
    'charges': [100, 200, 300, 400, 500]
})
targets = ['A', 'C']

mask = df['region'].isin(targets)
print(mask)

#출력코드
0     True
1    False
2     True
3     True
4    False
Name: region, dtype: bool

3.4. loc[cond]

정의
: Boolean 인덱싱을 이용해, cond가 True인 만 선택하여 새로운 DataFrame을 반환합니다. 

df.loc[BooleanSeries]

 

<예제 코드>

import pandas as pd

df = pd.DataFrame({
    'region': ['A', 'B', 'C', 'A', 'D'],
    'charges': [100, 200, 300, 400, 500]
})
targets = ['A', 'C']
mask = df['region'].isin(targets)

selected = df.loc[mask]
print(selected)

#출력결과
  region  charges
0      A      100
2      C      300
3      A      400

 

4. 피벗 테이블과 열지도의 활용

: pandas의 pivot_table() 을 활용하면 Excel의 피벗테이블과 동일한 표 형태의 집계 가능

 

4.1. DataFrame.pivot_table()

정의

: 행(index)과 열(columns)을 지정해 교차표 형태로 집계값을 계산해 주는 pandas 메서드입니다.

 

주요 파라미터

  • values : 집계할 수치형 컬럼 이름 또는 리스트
  • index : 결과의 행 인덱스로 사용할 컬럼 이름 또는 리스트
  • columns : 결과의 열 인덱스로 사용할 컬럼 이름 또는 리스트
  • aggfunc : 적용할 집계 함수 ('mean', 'sum', ['min','max'] 등)
  • margins : True로 설정하면 행/열 합계(전체) 추가
  • fill_value : NaN 셀을 채울 값

<기본 문법>

df.pivot_table(
    values='집계대상컬럼',
    index='행인덱스컬럼',
    columns='열인덱스컬럼',
    aggfunc='집계함수',
    margins=False,        # 합계 불포함
    fill_value=None       # NaN 대체값
)

 

<예제 코드>

import pandas as pd

df_ins = pd.DataFrame({
    'sex':    ['female','female','male','male'],
    'region': ['southwest','northeast','southwest','northeast'],
    'charges':[2500,        3500,       2100,       3000]
})

df_piv = df_ins.pivot_table(
    values='charges',
    index='sex',
    columns='region',
    aggfunc='mean'
)

print(df_piv)

#출력결과
region  northeast  southwest
sex                            
female     3500.0     2500.0
male       3000.0     2100.0

4.2. seaborn.heatmap()

참고: pandas만 사용해야 할 경우, plt.imshow(df.values, ...) 등으로 대체할 수 있습니다.

 

정의

: 2차원 데이터(배열 또는 DataFrame)를 색상 그리드로 시각화하여 패턴이나 분포를 한눈에 보여주는 함수입니다.

주요 파라미터

  • data : 2D 배열 또는 pandas DataFrame
  • annot : 셀 안에 수치값 표시 여부 (True/False)
  • fmt : 표시할 값의 포맷 (예: '.2f')
  • cmap : 색상 지도(컬러 맵) 이름 (예: 'Blues', 'viridis' 등)

<기본 문법>

import seaborn as sns
import matplotlib.pyplot as plt

sns.heatmap(
    data,       # 2D 데이터
    annot=True, # 셀 안에 숫자를 표시
    fmt='.2f',  # 소수점 둘째 자리까지
    cmap='Blues'
)
plt.show()

 

<예제 코드>

import seaborn as sns
import matplotlib.pyplot as plt
import pandas as pd

# pivot_table 결과를 그대로 사용
df_piv = pd.DataFrame({
    'northeast': [3500.0, 3000.0],
    'southwest': [2500.0, 2100.0]
}, index=['female','male'])

sns.heatmap(df_piv, annot=True, fmt='.0f', cmap='Blues')
plt.title("Region별 Charges 평균")
plt.xlabel("Region")
plt.ylabel("Sex")
plt.show()

 

예상 시각화

  • : female, male
  • : northeast, southwest
  • 각 셀에 평균비용(정수)이 표시된 파란 계열의 색상 그리드

5. 결과 데이터 저장

: 함수를 활용해서 분석 결과 데이터 저장 가능

 

5.1. 결과를 담을 폴더 만들기

%mkdir result
  • Jupyter/IPython 매직 커맨드(%mkdir)로 현재 작업 디렉터리에 result라는 이름의 새 폴더를 생성합니다.
  • 이미 폴더가 있으면 에러가 나므로, 필요하면 -p 옵션(리눅스 쉘)이나 사전에 존재 여부를 체크하세요.

5.2. 피벗 테이블 생성

df_pt1 = df_ins.pivot_table(
    index='region',     # 행 인덱스: region
    columns='smoker',   # 열 인덱스: smoker 여부
    values='charges',   # 집계 대상 컬럼: charges
    aggfunc='mean'      # 집계 함수: 평균
)
  • region별·smoker별로 charges의 평균을 계산해 2차원 표(데이터프레임) 형태로 만듭니다.

5.3. 결과 확인

df_pt1
  • 생성된 피벗 테이블을 출력해, 값이 잘 계산되었는지 확인합니다.

5.4. CSV 형식으로 저장

df_pt1.to_csv(
    './result/result.csv',  # 저장 경로 및 파일명
    index=True,             # 인덱스(여기서는 region)를 파일에도 함께 기록
    encoding='CP949'        # 한글 윈도우 환경 호환 인코딩 (UTF-8 가능)
)

 

  • to_csv() 메서드로 DataFrame을 CSV 파일로 내보냅니다.
  • index=True를 지정하면 행 인덱스(region)도 첫 열에 함께 기록됩니다.
  • encoding='CP949'는 주로 윈도우 한글 환경에서 Excel로 열 때 깨짐을 방지하기 위한 문자셋입니다.
  • 만약 UTF-8 환경이라면 encoding='utf-8-sig' 로 지정해도 됩니다.

 

데이터 처리 심화

주요 내용

  1. 변수 수정, 추가 및 제거
  2. 변수 형식 변환
  3. 결측값 처리 및 파생변수 생성

목표

  1. 분석 목적에 맞게 변수를 수정하고 파생 변수를 추가할 수 있다.
  2. 날짜 등 변수 형식을 활용할 수 있다.
  3. 결측값을 적절한 값으로 대체하는 방법을 확인한다.

 

1. 변수(열)의 수정, 추가, 제거

: pandas의 기본 기능과 메서드를 활용하여 변수를 추가 하거나 수정, 업데이트하거나 제거 가능
변수를 선택하듯 = 을 활용해서 변수를 추가하거나 업데이트 가능 

1.1. 변수 수정 및 추가

1.1.1. 변수(열) 수정

<문법>

df['기존컬럼명'] = 새로운값_or_시리즈

 

<설명>

: df['SECOND'] = 0 처럼, 이미 존재하는 컬럼 이름을 지정하면 해당 컬럼 전체를 새 값으로 덮어쓰며 수정합니다.

 
<예제>
df_own['SECOND'] = 0

SECOND 컬럼의 모든 값이 0으로 변경됩니다.

 

1.1.2. 변수(열) 추가

<문법>

df['새컬럼명'] = 값_or_시리즈

 

<설명>

: 존재하지 않던 컬럼 이름을 지정하면, 그 이름으로 새 컬럼을 추가하고 지정한 값(또는 연산 결과)을 채웁니다.

 

<예제>

df_own['FOURTH'] = 0

FOURTH라는 새 컬럼이 추가되고, 모든 행에 0이 채워집니다.

 

1.1.3. 추가한 변수 업데이트

<문법>

df['새컬럼명'] = df['다른컬럼명'] + 연산

 

<설명>

: 앞서 추가한 컬럼에 대해, 기존 컬럼을 참조해서 값을 재계산·업데이트할 수 있습니다.

 

<예제>

df_own['FOURTH'] = df_own['SECOND'] + 1

FOURTH 컬럼의 각 값이 SECOND + 1 연산 결과로 업데이트됩니다.

 

<전체흐름>

import pandas as pd

# 예제 DataFrame 생성
df_own = pd.DataFrame({
    'FIRST' : ['A', 'B', 'C', 'D'],
    'SECOND': [7, 6, 5, 8],
    'THIRD' : pd.date_range('2023-01-01', periods=4, freq='W-SAT')
})

# 1) 기존 컬럼 수정
df_own['SECOND'] = 0

# 2) 새 컬럼 추가
df_own['FOURTH'] = 0

# 3) 추가한 컬럼을 기존 컬럼 활용해 업데이트
df_own['FOURTH'] = df_own['SECOND'] + 1

print(df_own)

#출력결과
  FIRST  SECOND      THIRD  FOURTH
0     A       0 2023-01-07       1
1     B       0 2023-01-14       1
2     C       0 2023-01-21       1
3     D       0 2023-01-28       1

 

1.2. 객체 메서드와 Series 메서드의 비교

날짜시간 변수의 경우 월, 일, 요일, 시간 등 다양한 요소를 추출해서 변수로 추가할 수 있습니다.
Python은 개발언어로 객체의 형식에 매우 엄격하므로 메서드의 구분 필요합니다.
때문에 개별 날짜에 적용할 수 있는 메서드가 아닌 pandas Series 메서드 활용을 추천합니다.

 

1.2.1. 이론

<Python datetime 객체 메서드>

: datetime 타입의 단일 인스턴스에만 적용이 가능합니다.

single = df_own.loc[0, 'THIRD']
single.weekday()   # 0=월요일 … 6=일요일

 DataFrame/Series 전체에는 직접 호출 불가(에러 발생)합니다.

 

<pandas Series 메서드 및 dt 액세서>

DataFrame의 컬럼(Series)은 여러 값을 담은 구조이므로, 개별 객체 메서드를 바로 적용하면 실패

대신 .apply(lambda x: x.메서드()) 로 반복 호출하거나 벡터화된 Series.dt 액세서를 사용합니다.

Series.dt 안에는 날짜·시간 관련 속성·메서드가 모여 있어 빠르고 간편한 장점이 있습니다.

 

1.2.2. 주요 함수 및 문법

<개별 값 메서드 호출>

single = df_own.loc[0, 'THIRD']
single.weekday()
  • 용도: 단일 datetime 객체의 요일·월·일·시간 등 추출
  • 리턴: int (예: 5 → 토요일)

<apply() + 람다/함수>

df_own['DAY'] = df_own['THIRD'].apply(lambda x: x.weekday())

 

  • 용도: Series 각 요소에 Python 함수(또는 람다) 적용
  • 특징: 유연하지만 느림

<Series.dt 액세서 (권장)>

# 요일 (0=월 … 6=일)
df_own['WEEKDAY'] = df_own['THIRD'].dt.weekday

# 그 외 주요 속성
df_own['YEAR']  = df_own['THIRD'].dt.year
df_own['MONTH'] = df_own['THIRD'].dt.month
df_own['DAY']   = df_own['THIRD'].dt.day
df_own['HOUR']  = df_own['THIRD'].dt.hour
# (pandas 버전에 따라 dt.day_name() 로 요일명 추출)

 

  • 용도: 날짜·시간 컬럼에서 벡터화된 방식으로 일괄 추출
  • 장점: 내부 C/NumPy 연산으로 고속 처리, 코드도 간결

<전체예제>

import pandas as pd

# 예제 DataFrame
df_own = pd.DataFrame({
    'FIRST' : ['A','B','C','D'],
    'SECOND': [7,6,5,8],
    'THIRD' : pd.date_range('2023-01-01', periods=4, freq='W-SAT')
})

# 1) 개별 값 weekday()
print(df_own.loc[0,'THIRD'].weekday())  # → 5

# 2) apply() + lambda
df_own['DAY_APPLY'] = df_own['THIRD'].apply(lambda x: x.weekday())

# 3) dt 액세서
df_own['WEEKDAY'] = df_own['THIRD'].dt.weekday
df_own['MONTH']   = df_own['THIRD'].dt.month

print(df_own)

#출력결과
5
  FIRST  SECOND      THIRD  DAY_APPLY  WEEKDAY  MONTH
0     A       7 2023-01-07          5        5      1
1     B       6 2023-01-14          5        5      1
2     C       5 2023-01-21          5        5      1
3     D       8 2023-01-28          5        5      1

 

1.3. 조건을 활용한 값 변경, 생성

1.3.1. 이론

  • pandas에서는 DataFrame.loc[행조건, 열이름] = 값 형태로 특정 행·열만 골라 값을 할당할 수 있습니다.
  • 이때 행조건은 보통 Series(Boolean)로, Series.isin(), 비교 연산자(>, == 등) 등으로 만듭니다.
  • 조건에 맞지 않는 위치에는 아무런 변화가 일어나지 않으며, 새 열을 지정하면 그 위치만 값이 채워지고 나머지는 NaN(결측값) 상태가 됩니다.

1.3.2. 주요 메서드·문법


메서드 문법설명
Series.isin(리스트) Series 값이 리스트에 포함돼 있으면 True, 아니면 False
df.loc[cond] Boolean Series cond가 True인 행 전체 반환
df.loc[cond, 'col'] = 값 cond에 맞는 행의 특정 열(col) 값만 할당
df.loc[cond, ['col1','col2']] = 값_or_리스트 여러 열에 동시에 할당
df.loc[행인덱스목록, 'col'] = 값 위치 인덱스(정수 리스트)로 특정 행만 선택
(주의) df[0:2]['SECOND'] = 0 체인 인덱싱 → 경고 발생, loc 사용 권장

<예제 코드>

import pandas as pd

# 예제 DataFrame
df_own = pd.DataFrame({
    'FIRST' : ['A','B','C','D'],
    'SECOND': [7,6,5,8],
    'FOURTH': [10,20,30,40]
})

# 1) 조건 생성: FIRST가 'A' 또는 'B'
cond = df_own['FIRST'].isin(['A','B'])

# 2) 조건에 맞는 행 전체 보기
print(df_own.loc[cond])

# 3) 조건에 맞는 행의 'FOURTH' 값만 0으로 변경
df_own.loc[cond, 'FOURTH'] = 0
print(df_own)

# 4) 조건에 맞는 행에만 새 열 'OPTIONAL' 생성·값 할당
df_own.loc[cond, 'OPTIONAL'] = 9999
print(df_own)

# 5) 위치 인덱스(0,1번 행)의 'SECOND'를 0으로 변경 (in-place)
df_own.loc[[0,1], 'SECOND'] = 0
print(df_own)

# → 체인 인덱싱(df_own[0:2]['SECOND'] = 0) 대신 loc 권장

 

<예상 출력>

 

df_own.loc[cond]

  FIRST  SECOND  FOURTH
0     A       7       0
1     B       6       0

 

FOURTH 변경 후

  FIRST  SECOND  FOURTH
0     A       7       0
1     B       6       0
2     C       5      30
3     D       8      40

 

OPTIONAL 생성 후

  FIRST  SECOND  FOURTH  OPTIONAL
0     A       7       0    9999.0
1     B       6       0    9999.0
2     C       5      30       NaN
3     D       8      40       NaN

 

위치 인덱스 할당 후

  FIRST  SECOND  FOURTH  OPTIONAL
0     A       0       0    9999.0
1     B       0       0    9999.0
2     C       5      30       NaN
3     D       8      40       NaN

 

1.4. 변수 제거

drop()

관측치와 변수를 제거할 수 있는데 index columns를 활용합니다.
axis=옵션에 따라 axis=0이면 관측치를 제거하고 axis=1이면 변수를 제거합니다.

columns=이라는 옵션을 명시해서 변수를 제거하는 것이 가장 명확하고 실수를 줄일 수 있습니다.

 

<함수 정의>

DataFrame.drop(
    labels=None,
    axis=0,
    index=None,
    columns=None,
    level=None,
    inplace=False,
    errors='raise'
)

 

<파라미터 설명>

인자 축(axis) 역할
labels 0 또는 1 제거할 행 또는 열 이름(단일값 또는 리스트)
axis 0 / 1 0: 행 제거, 1: 열 제거
index 0 labels와 동일하게 행 인덱스만 지정할 때 사용
columns 1 labels와 동일하게 열 이름만 지정할 때 사용
level 멀티인덱스의 특정 레벨에서 제거할 때 사용
inplace True 면 원본을 직접 수정, False 면 새 DataFrame 반환 (기본)
errors 'raise'(기본): 지정 항목이 없으면 에러 발생
'ignore': 없는 항목 무시

<기본 문법>

# 1) 열 제거 (axis 지정)
df2 = df.drop(labels='col_name', axis=1)

# 2) 열 제거 (columns 옵션)
df2 = df.drop(columns=['col1', 'col2'])

# 3) 행 제거 (axis=0)
df2 = df.drop(labels=[0, 3], axis=0)

# 4) 원본 직접 수정
df.drop(columns='col_name', inplace=True)

 

<예제>

import pandas as pd

df = pd.DataFrame({
    'A': [1, 2, 3],
    'B': [4, 5, 6],
    'C': [7, 8, 9]
})

# 열 B 제거
df2 = df.drop(columns=['B'])
# df2: columns ['A','C']

# 행 인덱스 0,2 제거
df3 = df.drop(index=[0,2])
# df3: only index 1 remains

# 원본에서 열 C 바로 제거
df.drop('C', axis=1, inplace=True)
# df: columns ['A','B']

 

1.5. 변수 이름 변경

: 변수이름을 바꾸고 싶을 때는 DataFrame의 메서드 rename() 을 활용합니다.
이때 columns= 옵션을 활용하고 딕셔너리 형식으로 기존변수이름과 새변수이름을 콜론으로 연결합니다.

 

1.5.1. DataFrame.rename() 메서드

 

<함수 정의 (Signature)>

DataFrame.rename(
    mapper=None,      # 축 전체의 이름 매핑(dict) 지정
    index=None,       # 행 인덱스 리네임(dict)
    columns=None,     # 열 이름 리네임(dict)
    axis=None,        # 0 or 'index', 1 or 'columns' (자동 판단)
    inplace=False,    # True로 설정하면 원본 수정, False(기본)는 새 DataFrame 반환
    errors='ignore'   # 'raise'면 없는 이름에 에러, 'ignore'면 무시
)

 

<문법>

# 새 DataFrame 반환
df2 = df.rename(columns={'old1':'new1', 'old2':'new2'})

# 원본을 직접 수정
df.rename(columns={'old':'new'}, inplace=True)

 

1.5.2. columns 속성 직접 할당

 

<문법>

df.columns = ['new1', 'new2', ...]

 

  • 전체 컬럼 개수와 반드시 일치하는 리스트여야 합니다.
  • in-place로 바로 변경됩니다.

<예제 및 출력 결과>

import pandas as pd

# 1) 원본 DataFrame
df = pd.DataFrame({
    'FIRST' : ['A','B','C'],
    'SECOND': [7,6,5],
    'THIRD' : pd.date_range('2023-01-01', periods=3, freq='D')
})
print("원본 df:")
print(df)

# 2) rename() 사용 (새 DataFrame)
df2 = df.rename(columns={'FIRST':'var1', 'SECOND':'var2'})
print("\nrename(columns={'FIRST':'var1','SECOND':'var2'}) → df2:")
print(df2)

# 3) rename(inplace=True) 사용
df3 = df.copy()
df3.rename(columns={'THIRD':'date3'}, inplace=True)
print("\nrename(columns={'THIRD':'date3'}, inplace=True) → df3:")
print

 

2. 결측값 처리

결측값은 다양한 이유로 발생합니다.

  • 애초에 값이 없는 경우
  • 값이 있으나 사람 실수로 누락한 경우
  • 센서, 통신망 등의 오류로 값이 들어오지 않은 경우

먼저 결측값 존재 여부 확인하고, 대체를 할 지 그대로 둘 지를 결정하고,
대체를 한다면 어떤 값으로 채울지도 고민하여 지정해야합니다.

 

아래의 명령어를 활용하면 전체 데이터에서 결측값이 있는 관측치나 변수를 확인할 수 있습니다.

# isnull 함수를 활용한 결측값 필터
cond = df_na['info1'].isnull()
# df_na[cond]
df_na[~cond]

# 여러개의 변수의 결측값 확인 및 필터
cond = df_na['info1'].isnull() | df_na['info3'].isnull()
# df_na[cond]
df_na[~cond]

# any 함수를 활용한 모든열의 결측값 필터
df_na.isnull()
cond = df_na.isnull().any(axis=1)
df_na[~cond]

# any 함수를 활용한 부분열의 결측값 필터
cond = df_na[['info1', 'info3']].isnull().any(axis=1)
df_na[~cond]

 

2.1. 결측값 포함 관측치 제거

: 결측값이 있는 관측치에 대응하는 가장 간단한 방법은 결측치를 포함한 변수나 관측치를 제거하는 것을 말합니다.

 

dropna()

이론

  • 결측치(missing value, NaN) 가 포함된 행(row) 또는 열(column) 을 삭제하는 함수입니다.
  • 데이터 정제(cleaning) 과정에서 많이 사용하며, 삭제 기준을 세밀하게 조정할 수 있습니다.

문법

DataFrame.dropna(
    axis=0,       # 0: 행 제거, 1: 열 제거
    how='any',    # 'any': 하나라도 NaN이 있으면 삭제  
                  # 'all': 모두 NaN인 경우에만 삭제
    thresh=None,  # 남아 있어야 할 최소 비-NaN 개수 (정수)
    subset=None,  # 검사할 특정 행/열 레이블 리스트
    inplace=False # True: 원본 수정, False: 복사본 반환
)

 

  • axis
    • axis=0 (기본): 행 단위로 NaN 검사 → 해당 행 삭제
    • axis=1: 열 단위로 NaN 검사 → 해당 열 삭제
  • how
    • 'any' (기본): NaN이 하나라도 있으면 삭제
    • 'all': 모든 값이 NaN일 때만 삭제
  • thresh
    • 예: thresh=2 이면 “2개 이상의 비-NaN 값이 있는” 항목만 남깁니다.
  • subset
    • 예: subset=['age','score'] → 이 두 컬럼에서만 NaN 검사

간단 예제 및 출력 결과

import pandas as pd
import numpy as np

# 예제 DataFrame 생성
df = pd.DataFrame({
    'name': ['Alice', 'Bob', None,   'Dave'],
    'age':  [25,      np.nan, 30,    22],
    'score':[85,      92,      np.nan, 88]
})
print(df)

#출력결과
    name   age  score
0  Alice  25.0   85.0
1    Bob   NaN   92.0
2   None  30.0    NaN
3   Dave  22.0   88.0

 

기본 호출 (행 단위, how='any')

# NaN이 하나라도 있는 행 모두 삭제
df_clean = df.dropna()
print(df_clean)

#출력결과
    name   age  score
3   Dave  22.0   88.0

 

how='all' (모두 NaN일 때만 삭제)

# 모든 값이 NaN인 행만 삭제
df_all = df.dropna(how='all')
print(df_all)

#출력결과
    name   age  score
0  Alice  25.0   85.0
1    Bob   NaN   92.0
2   None  30.0    NaN
3   Dave  22.0   88.0

 

subset 활용 (특정 컬럼 기준)

# 모든 NaN을 0으로 채움
df_fill0 = df.fillna(0)
print(df_fill0)

#출력결과
    name   age  score
0  Alice  25.0   85.0
1    Bob   0.0   92.0
2   None  30.0    0.0
3   Dave  22.0   88.0

2.2. 결측값 대체

: 일반적으로 결측값을 그대로 두거나 다음과 같이 결측값을 적절한 값으로 대체하고 활용할 수 있습니다.

fillna()

이론

  • 결측치(missing value, NaN) 를 원하는 값으로 대체(replace) 하는 함수입니다.
  • 결측치를 0, 평균, 이전 유효값 등으로 채워넣어 데이터 분석·모델 학습 시 오류를 방지합니다.

문법

DataFrame.fillna(
    value=None,    # 채워넣을 스칼라, 딕셔너리, Series, 또는 DataFrame
    method=None,   # 'ffill' (앞의 값), 'bfill' (뒤의 값) 등으로 결측 전후값 복사
    axis=None,     # None/’index’: 행 기준, ’columns’: 열 기준
    inplace=False, # True: 원본 수정, False: 복사본 반환
    limit=None     # 연속으로 채울 최대 개수
)
  • value
    • 스칼라: 모든 결측을 동일 값으로 채움 (value=0)
    • 딕셔너리: 컬럼별로 다른 값 지정 ({'age':0, 'score':-1})
  • method
    • method='ffill': 바로 앞(위)의 유효한 값으로 채움
    • method='bfill': 바로 뒤(아래)의 유효한 값으로 채움
  • limit
    • limit=1이면 연속된 NaN 중 앞에서부터 1개만 채움

간단 예제 및 출력 결과

import pandas as pd
import numpy as np

# 예제 DataFrame 생성
df = pd.DataFrame({
    'name':   ['Alice', 'Bob',   None,   'Dave'],
    'age':    [25,      np.nan, 30,      22],
    'score':  [85,      92,      np.nan,  88]
})
print(df)

#출력결과
    name   age  score
0  Alice  25.0   85.0
1    Bob   NaN   92.0
2   None  30.0    NaN
3   Dave  22.0   88.0

 

스칼라 값으로 채우기 (value=0)

# 모든 NaN을 0으로 채움
df_fill0 = df.fillna(0)
print(df_fill0)

#출력결과
    name   age  score
0  Alice  25.0   85.0
1    Bob   0.0   92.0
2   None  30.0    0.0
3   Dave  22.0   88.0

 

컬럼별로 다른 값 지정 (value에 dict)

# 'age'는 평균으로, 'score'는 -1로 채움
mean_age = df['age'].mean()
df_fill_dict = df.fillna({'age': mean_age, 'score': -1})
print(df_fill_dict)

#출력결과
    name        age  score
0  Alice  25.000000   85.0
1    Bob  25.666667   92.0
2   None  30.000000   -1.0
3   Dave  22.000000   88.0

 

전후 유효값으로 채우기 (method='ffill', limit)

# 앞의 값으로 채우기, 연속 NaN 중 첫 1개만
df_ffill = df.fillna(method='ffill', limit=1)
print(df_ffill)

#출력결과
    name   age  score
0  Alice  25.0   85.0
1    Bob  25.0   92.0
2    Bob  30.0   92.0
3   Dave  22.0   88.0

 

3. 변수 형식 변환 및 파생변수 생성

: read_csv() 로 데이터를 불러오면 적당한 형식으로 지정되는데, 가끔 형식을 직접 바꿔야할 상황이 있습니다.
상황에 따라 날짜에서 요일을 추출하듯이 기존 변수를 활용해서 새로운 변수를 추가해서 분석에 활용해야하는 경우도 있습니다.

 

3.1. 변수 형식의 확인/변환

DataFrame에서는 다음과 같은 Series 형식을 활용합니다.

 

3.1.1. .dtypes

이론

  • DataFrame의 각 컬럼이 어떤 데이터 타입(dtype)을 가지고 있는지 알려주는 속성(property) 입니다.
  • 데이터 정제·변환 작업 전후에 타입을 확인할 때 자주 사용합니다.

문법

DataFrame.dtypes

 

예제

import pandas as pd

# 예제 DataFrame
df = pd.DataFrame({
    'id':   [1,    2,    3],
    'val':  ['10', '20', '30'],
    'flag': [True, False, True]
})

print(df)
print(df.dtypes)

#출력결과
   id val   flag
0   1  10   True
1   2  20  False
2   3  30   True

id       int64
val     object
flag       bool
dtype: object

 

3.1.2. .astype()

이론

  • Series나 DataFrame의 데이터 타입을 변환(cast)하는 메서드입니다.
  • 예를 들어 문자열로 된 숫자 컬럼을 정수나 실수로 바꾸거나, 불리언을 정수(0/1)로 바꿀 때 사용합니다.

문법

# Series에 단일 dtype 적용
Series.astype(dtype, copy=True, errors='raise')

# DataFrame에 컬럼별 dtype 적용
DataFrame.astype(
    dtype,        # 스칼라(dtype) 또는 {'col1':dtype1, 'col2':dtype2, ...}
    copy=True,    # True면 복사본 반환, False면 원본 자체 수정 가능
    errors='raise'# 'raise' (기본): 변환 실패 시 에러  
                  # 'ignore': 실패한 경우 그냥 원본 유지
)

 

예제

# 같은 df 사용
print(df.dtypes)
# id       int64
# val     object
# flag       bool

# 1) 'val' 컬럼을 문자열→정수로 변환
df['val'] = df['val'].astype(int)
print(df.dtypes)
# id       int64
# val      int64
# flag      bool

# 2) 불리언을 0/1 정수로 변환
df['flag_int'] = df['flag'].astype(int)
print(df)
print(df.dtypes)

#출력결과
   id  val   flag  flag_int
0   1   10   True         1
1   2   20  False         0
2   3   30   True         1

id          int64
val         int64
flag          bool
flag_int     int64
dtype: object

# 3) DataFrame 전체를 실수 타입으로 변환 (copy=True)
df_float = df.astype(float)
print(df_float.dtypes)

#출력결과
id           float64
val          float64
flag         float64
flag_int     float64
dtype: object

 

요약하자면

 

  • .dtypes 로 현재 타입 확인
  • .astype() 으로 원하는 타입으로 변환

입니다!


[참고] 범주형 데이터 사용의 이점

 

이론 & 이점

  1. 순서(order) 부여
    • 범주형에 순서를 지정하면 "Low" < "Medium" < "High"처럼 자연스러운 크기 관계를 만들 수 있습니다.
  2. 메모리·성능 최적화
    • 내부적으로 정수 코드(integer codes)로 저장해 메모리 사용량을 줄이고, 그룹 연산·정렬 성능이 향상됩니다.
  3. 그래프 그리기
    • 카테고리 순서대로 x축 배치가 보장되어, 시각화 시 레이블 정렬을 일일이 지정할 필요가 없습니다.

문법

from pandas.api.types import CategoricalDtype

# 1) 단순 카테고리로 변환
df['col'] = df['col'].astype('category')

# 2) 순서가 있는 카테고리로 변환
cat_type = CategoricalDtype(
    categories=['Low','Medium','High'],
    ordered=True
)
df['priority'] = df['priority'].astype(cat_type)

 

 

  • .astype('category') 만 쓰면 무순서 범주형이 됩니다.
  • CategoricalDtype 으로 순서(ordered) 를 지정할 수 있습니다.

3.2. 수치형 변수의 구간화

: 수치형 변수는 그대로 활용하기 보다는 구간화하는 경우가 많습니다.
cut() 이나 qcut() 함수를 주로 활용합니다.

 

3.2.1. cut()

  • 등간격(equal-width) 또는 사용자가 지정한 구간 경계로 나눕니다.

3.2.2. qcut()

  • 등비율(equal-frequency, 분위수 기반) 로 나눠, 각 구간에 거의 동일한 개수의 샘플이 들어가게 합니다.

3.3. 그룹 내 순위, 이동, 누적 변수 생성

: 데이터 분석 과정에서 그룹별로 순위를 매기거나, 직전 값과 비교를 통해서 변화량 등을 확인하기도 합니다. 뿐만 아니라 이동 평균이나 누적 최댓값 등을 계산하기도 합니다.

 

3.3.1. 이동(shift)

이론

  • 이동(shift) 은 시계열 혹은 순서가 있는 데이터에서 “한 칸 위/아래”의 값을 가져오는 함수입니다.
  • 그룹별로 이전 값(prev)·다음 값(next)을 비교하거나 변화량을 계산할 때 사용합니다.

문법

# 기본 형식
Series.shift(periods=1, fill_value=None)

# groupby와 함께 사용
df['new_col'] = df.groupby('그룹키')['대상컬럼'].shift(periods=1)   # 이전값
df['new_col2'] = df.groupby('그룹키')['대상컬럼'].shift(periods=-1)  # 다음값

 

  • periods
    • 양수: 과거(위) 방향으로 이동
    • 음수: 미래(아래) 방향으로 이동
  • fill_value
    • 이동으로 생긴 빈 칸에 채울 값

예시 및 출력

import pandas as pd

df = pd.DataFrame({
    'grp': ['A','A','A','B','B','B'],
    'v':   [10, 20, 15,   5, 10,   5]
})

# 이전 값(prev) 한 칸 가져오기
df['v_prev'] = df.groupby('grp')['v'].shift(1)

# 다음 값(next) 한 칸 가져오기
df['v_next'] = df.groupby('grp')['v'].shift(-1)

print(df)

#출력코드
  grp   v  v_prev  v_next
0   A  10     NaN    20.0
1   A  20    10.0    15.0
2   A  15    20.0     NaN
3   B   5     NaN    10.0
4   B  10     5.0     5.0
5   B   5    10.0     NaN

 

3.3.2. 순위(rank)

이론

  • 순위(rank) 는 같은 그룹 내에서 값의 상대적 크기를 1, 2, 3… 과 같이 매겨주는 함수입니다.
  • 데이터의 크기 순서에 따른 위치(feature)로 활용하거나, 백분위(percentile) 계산의 기초로 사용됩니다.

문법

# 기본 형식
Series.rank(ascending=True, method='average', pct=False)

# groupby와 함께 사용
df['rank'] = df.groupby('그룹키')['대상컬럼'] \
               .rank(ascending=True, method='first')

 

 

  • ascending
    • True (기본): 작은 값이 1위
    • False: 큰 값이 1위
  • method
    • 'average': 동률(rank 동점)일 때 평균 순위 부여
    • 'min'/'max': 동률일 때 각각 최소·최대 순위 부여
    • 'first': 등장 순서대로 1,2,… 부여
    • 'dense': 동률이면 다음 순위 건너뛰지 않음
  • pct
    • True로 하면 순위를 전체 개수로 나눈 0~1 사이 비율 리턴

예시 및 출력

import pandas as pd

df = pd.DataFrame({
    'grp': ['A','A','A','B','B','B'],
    'v':   [10, 20, 15,   5, 10,   5]
})

# 그룹별 v의 크기순(작→큰)으로 순위 매기기
df['v_rank'] = df.groupby('grp')['v'] \
                 .rank(ascending=True, method='first')

print(df)

#출력결과
  grp   v  v_rank
0   A  10     1.0
1   A  20     3.0
2   A  15     2.0
3   B   5     1.0
4   B  10     3.0
5   B   5     2.0

 

 

3.3.3. 누적합(cumsum)

이론

  • 누적합(cumulative sum) 은 그룹별로 값을 차례차례 더해가며 누적된 합계를 계산합니다.
  • 시계열 분석에서 누적 트렌드 추적, 점수 누적 합계 계산 등에 쓰입니다.

문법

# 기본 형식
Series.cumsum()

# groupby와 함께 사용
df['cum_sum'] = df.groupby('그룹키')['대상컬럼'].cumsum()

 

예시 및 출력

import pandas as pd

df = pd.DataFrame({
    'grp': ['A','A','A','B','B','B'],
    'v':   [10, 20, 15,   5, 10,   5]
})

# 그룹별 v의 누적합
df['v_cumsum'] = df.groupby('grp')['v'].cumsum()

print(df)

#출력결과
  grp   v  v_cumsum
0   A  10        10
1   A  20        30
2   A  15        45
3   B   5         5
4   B  10        15
5   B   5        20

4. 날짜시간 변수 활용

: 날짜시간 변수에서 요소를 추출할 수 있고, 날짜시간별로 집계된 데이터로 시각화가 가능합니다.

 

4.1 문법

4.1.1. 날짜형 변환

# str/object → datetime 타입으로 변환
df['date'] = pd.to_datetime(df['date'], format='%Y-%m-%d')
# format 은 데이터에 맞춰 지정 (예: '%Y/%m/%d %H:%M')

 

4.1.2. 요소 추출 (.dt accessor)

# 연·월·일 · 시·분·초 · 요일 · 주차 등
df['year']      = df['date'].dt.year
df['month']     = df['date'].dt.month
df['day']       = df['date'].dt.day
df['hour']      = df['date'].dt.hour
df['weekday']   = df['date'].dt.weekday   # 0=월요일 … 6=일요일
df['day_name']  = df['date'].dt.day_name()# 'Monday' 등
df['weekofyear']= df['date'].dt.isocalendar().week

 

4.1.3. 시계열 집계 (resample)

# 인덱스를 datetime으로 설정한 뒤
ts = df.set_index('date')['value']

# 일별 합계
daily = ts.resample('D').sum()    # 'D': calendar day
# 월별 평균
monthly = ts.resample('M').mean() # 'M': month end
# 시간별 최대값
hourly = ts.resample('H').max()   # 'H': hourly

 

4.1.4. 그룹별 집계

# month 컬럼으로 그룹화
df.groupby(df['date'].dt.month)['value'].sum()

# 요일별 평균
df.groupby(df['date'].dt.weekday)['value'].mean()

 

<마무리>

오늘은 파이썬 데이터 전처리 기초 마지막날이네요. 벌써 시간이 이렇게 흐르다니...!

기초 문법부터 파일 결합, 전처리, 집계, 시각화, 심화 전처리까지 ‘끝에서 끝까지’ 데이터 분석 과정을 쫙 펼쳐 보여줘서 더욱 공부하기 편한 것 같았습니다!

또한 pd.merge, groupby·agg, pivot_table부터 cut·qcut, shift·rank·cumsum, .dt·resample 등 실제 업무의 핵심 함수들로을 배울 수 있어 좋았습니다.

5일동안 파이썬 데이터 전처리 기초를 설명해주신 김상일 교수님, 감사드립니다!!!

내일부터는 데이터 분석 및 시각화를 배운다는데 두근두근 기대가되군요~