| 함수 | 기능/설명 | 예시 코드 |
|---|---|---|
sum() | 합계 | df['col'].sum() |
mean() | 평균 | df['col'].mean() |
count() | 개수(결측치 제외) | df['col'].count() |
max() | 최댓값 | df['col'].max() |
min() | 최솟값 | df['col'].min() |
std() | 표준편차 | df['col'].std() |
var() | 분산 | df['col'].var() |
median() | 중앙값 | df['col'].median() |
describe() | 전체 요약(평균, 사분위수 등) | df.describe() |
axis=0(기본): 컬럼axis=1: 행 "왼쪽에서 오른쪽으로(가로 방향)" → 열(column)을 따라 연산 → 행 단위 계산| 함수 | axis=0 (기본) | axis=1 | |
|---|---|---|---|
sum() | 각 컬럼의 합 | 각 행의 합 | |
mean() | 각 컬럼의 평균 | 각 행의 평균 | |
dropna() | 결측치 있는 행 삭제 | 결측치 있는 열 삭제 | |
drop() | 행 삭제 | 열 삭제 | |
sort_values() | (컬럼명 기준 정렬, axis=0만) | (axis=1은 거의 안 씀) | |
apply() | 각 컬럼에 함수 적용 | 각 행에 함수 적용 |
import pandas as pd
df = pd.DataFrame({
'A': [1, 2, 3],
'B': [10, 20, 30],
'C': [100, 200, 300]
})
# 1) axis=0 (컬럼별, 기본)
print(df.sum(axis=0))
# A 6
# B 60
# C 600
# 각 컬럼의 합
# 2) axis=1 (행별)
print(df.sum(axis=1))
# 0 111 (1+10+100)
# 1 222 (2+20+200)
# 2 333 (3+30+300)
# 각 행의 합
# 3) dropna() 예시
df2 = pd.DataFrame({'A':[1, None, 3], 'B':[4, 5, None]})
print(df2.dropna(axis=0)) # 결측치 있는 "행" 삭제 (default)
print(df2.dropna(axis=1)) # 결측치 있는 "열" 삭제
# 4) drop() 예시
print(df.drop(index=0)) # 첫 번째 "행" 삭제 (axis=0)
print(df.drop(columns='B')) # 'B' 컬럼 삭제 (axis=1과 같음)
print(df.drop('B', axis=1)) # 'B' 컬럼 삭제 (axis=1)
axis=0 ↓
┌─────┐
│ A │
│ B │
│ C │
└─────┘
<-- axis=1
axis=0: 세로 방향, 각 컬럼(열)에 대해 함수 적용
axis=1: 가로 방향, 각 행(row)에 대해 함수 적용
sum, mean, std, min, max, apply, dropna, drop, fillna 등
거의 모든 판다스 연산에서 axis를 바꿔가며 쓸 수 있음
헷갈릴 때는
import pandas as pd
df = pd.DataFrame({
'성별': ['남', '여', '여', '남', '여'],
'점수': [80, 90, 75, 85, 95],
'학년': [1, 2, 1, 3, 2]
})
g = df.groupby('성별')
print(g['점수'].mean())
# 성별
# 남 82.5
# 여 86.7
g = df.groupby(['성별', '학년'])
print(g['점수'].mean())
g = df.groupby('성별')['점수'].agg(['mean', 'max', 'min'])
print(g)
# mean max min
# 성별
# 남 82.5 85 80
# 여 86.7 95 75
g = df.groupby('성별').agg({'점수': ['mean', 'std'], '학년': 'max'})
df['성별평균'] = df.groupby('성별')['점수'].transform('mean')
# 평균 점수가 85 이상인 그룹만 남김
df.groupby('성별').filter(lambda x: x['점수'].mean() >= 85)
apply 기본 사용법
df.apply(함수, axis=0 또는 1)
함수: 적용할 함수 (직접 만들 수도 있고, 파이썬 내장 함수도 가능)axis: 축 방향axis=0 → 세로 방향 (열 단위로) 적용axis=1 → 가로 방향 (행 단위로) 적용Series에서는 axis를 지정하지 않아도 됨
def custom_func(grp):
return grp['점수'].sum() / (grp['점수'].count() + 1)
df.groupby('성별').apply(custom_func)
# as_index = False 옵션
df.groupby('성별', as_index=False)['점수'].mean()
# 결과: '성별'이 컬럼으로 나옴(인덱스 아님
as_index=False 옵션으로 컬럼으로 유지 가능groupby는 그룹 컬럼을 인덱스로 만든다import pandas as pd
df = pd.DataFrame({
'과일': ['사과', '사과', '바나나', '바나나', '바나나'],
'가격': [1000, 1500, 500, 700, 800],
'수량': [1, 2, 3, 2, 1]
})
result = df.groupby('과일').sum()
print(result) 결과:
가격 수량
과일
바나나 2000 6
사과 2500 3
groupby('과일') 했더니, 과일 컬럼이 인덱스로 변함
그리고 가격, 수량은 그룹별로 합쳐짐
요약: 기본 설정은 as_index=True 이기 때문에 그룹핑한 컬럼이 인덱스가 됨
as_index=False를 주면, 그룹 컬럼을 인덱스가 아니라 컬럼으로 유지할 수 있다as_index=False예시:
result = df.groupby('과일', as_index=False).sum()
print(result)
결과:
과일 가격 수량
0 바나나 2000 6
1 사과 2500 3
과일이 인덱스가 아니라, 그냥 컬럼으로 남음
DataFrame 구조도 더 깔끔하게 유지.
| 상황 | 설명 | 결과 |
|---|---|---|
as_index=True (기본값) | 그룹핑 컬럼을 인덱스로 보냄 | 결과에서 컬럼이 인덱스에 들어감 |
as_index=False | 그룹핑 컬럼을 컬럼으로 유지 | 결과에서 컬럼이 그대로 남아있음 |
as_index=True: 분석/집계용 테이블 만들 때 좋음 (ex: pivot, multi-index 분석)
as_index=False: 결과를 다시 다른 컬럼들과 합치거나 쉽게 가공할 때 유리함
예시:
# 그룹 결과를 원본 데이터랑 merge하고 싶을 때
grouped = df.groupby('과일', as_index=False).sum()
merged = pd.merge(df, grouped, on='과일')
→ 이럴 때 as_index=False가 없으면 합치기 어려움
pd.pivot_table(df, index='성별', values='점수', aggfunc='mean')
pd.pivot_table(df, index='성별', columns='학년', values='점수', aggfunc='mean', fill_value=0)
index, columns에 각각 기준 넣기 가능aggfunc에 여러 함수도 가능(리스트로)Pandas에서 pd.pivot_table() 함수
엑셀 피벗 테이블과 거의 같음
데이터를 그룹핑해서 집계(aggregation)하고 요약(summary)하는 데 최적화
특히 2개 이상의 기준(행+열)을 기준으로 통계치 계산할 때 아주 유용
pd.pivot_table(dataframe, index=기준_행, columns=기준_열, values=대상_값, aggfunc=집계함수, fill_value=대체값)
| 파라미터 | 설명 |
|---|---|
index | 행(세로)로 사용할 컬럼 |
columns | 열(가로)로 사용할 컬럼 |
values | 집계할 대상 값 (숫자형 컬럼) |
aggfunc | 적용할 집계 함수 (평균, 합계, 최대값 등) |
fill_value | 결과에 NaN이 나오면 이걸로 채워라 |
import pandas as pd
df = pd.DataFrame({
'성별': ['남', '여', '남', '여', '남', '여'],
'학년': [1, 1, 2, 2, 3, 3],
'점수': [80, 90, 70, 85, 88, 95]
})
print(df)
df 내용
| 성별 | 학년 | 점수 | |
|---|---|---|---|
| 0 | 남 | 1 | 80 |
| 1 | 여 | 1 | 90 |
| 2 | 남 | 2 | 70 |
| 3 | 여 | 2 | 85 |
| 4 | 남 | 3 | 88 |
| 5 | 여 | 3 | 95 |
pd.pivot_table(df, index='성별', values='점수', aggfunc='mean')
결과:
| 성별 | 점수 |
|---|---|
| 남 | 79.333333 |
| 여 | 90.0 |
→ 성별로 점수 평균을 구함
pd.pivot_table(df, index='성별', columns='학년', values='점수', aggfunc='mean')
결과:
| 학년 | 1 | 2 | 3 |
|---|---|---|---|
| 성별 | |||
| 남 | 80.0 | 70.0 | 88.0 |
| 여 | 90.0 | 85.0 | 95.0 |
→
행: 성별
열: 학년
값: 평균 점수으로 교차표를 만든 거야.
fill_value=pd.pivot_table(df, index='성별', columns='학년', values='점수', aggfunc='mean', fill_value=0)
NaN 대신 0으로 채워준다.
특히 데이터가 빠질 수 있는 경우에 유용.
aggfunc 여러 개 적용할 수도 있어!pd.pivot_table(df, index='성별', values='점수', aggfunc=['mean', 'max', 'min'])
결과:
| 성별 | mean | max | min |
|---|---|---|---|
| 남 | 79.333333 | 88 | 70 |
| 여 | 90.0 | 95 | 85 |
성별별로 평균, 최대, 최소 점수를 모두 계산해서 보여줘.
aggfunc에 리스트를 넣으면 여러 집계 결과를 한꺼번에 보여줄 수 있어.
| 항목 | 설명 | 예시 |
|---|---|---|
| 단일 집계 | 한 가지 기준으로 통계 | 평균점수만 |
| 다중 집계 | 여러 기준으로 통계 | 평균, 최대, 최소 동시에 |
| 여러 index, columns | 행, 열 모두 기준 설정 가능 | 성별+학년별 평균점수 |
| fill_value | NaN 대신 다른 값 채우기 | fill_value=0 |
pd.crosstab(df['성별'], df['학년'])
margins=True: 행/열의 총합normalize=True: 비율(%)로 변환normalize 옵션 | 의미 | 합계가 1 되는 기준 |
|---|---|---|
True | 전체 데이터 대비 비율 | 전체 합계 |
'index' | 행별 (성별 그룹별) 비율 | 행별 합계 |
'columns' | 열별 (학년 그룹별) 비율 | 열별 합계 |
pivot_table vs crosstab 차이| 항목 | pivot_table | crosstab |
|---|---|---|
| 용도 | 수치 데이터 집계 (sum, mean 등) | 범주형 데이터 빈도수 계산 |
| 대상 데이터 | 수치형 중심 | 범주형 중심 |
| 집계 함수 | 자유롭게 지정 (aggfunc=) | 기본은 count(빈도) |
쉽게 말하면:
pivot_table은 숫자 평균/합 구할 때,crosstab은 범주를 셀때.df_grouped = df.groupby(['성별', '학년'])['점수'].mean().reset_index()
.set_index(), .reset_index(), .stack(), .unstack() 등.set_index()특정 컬럼을 인덱스로 설정하는 메서드
df.set_index('컬럼명')import pandas as pd
df = pd.DataFrame({
'이름': ['홍길동', '이순신', '강감찬'],
'나이': [30, 40, 50],
'점수': [80, 90, 100]
})
df.set_index('이름') 결과:
| 이름 | 나이 | 점수 |
|---|---|---|
| 홍길동 | 30 | 80 |
| 이순신 | 40 | 90 |
| 강감찬 | 50 | 100 |
'이름'이 인덱스로 설정되었고,
'나이', '점수'는 그대로 컬럼으로 남음.
.reset_index()"인덱스를 풀어 컬럼으로 만들기" (원래 데이터처럼 돌리기)
df.reset_index()
기존 인덱스 → 컬럼으로 이동
인덱스는 0,1,2 숫자 인덱스로 초기화
df2 = df.set_index('이름')
df2.reset_index()
결과:
| 이름 | 나이 | 점수 | |
|---|---|---|---|
| 0 | 홍길동 | 30 | 80 |
| 1 | 이순신 | 40 | 90 |
| 2 | 강감찬 | 50 | 100 |
'이름'이 다시 컬럼으로 복구됐어.
인덱스는 기본 숫자 0,1,2로 초기화.
.stack()"열(columns)을 행(index)으로 내려서 세로로 쌓기"
컬럼들을 행으로 바꾼다.
데이터가 좁고 길게(long format) 변함.
df.stack()
df2 = df.set_index('이름')
df2.stack()
결과:
| 이름 | 값 | |
|---|---|---|
| 홍길동 | 나이 | 30 |
| 홍길동 | 점수 | 80 |
| 이순신 | 나이 | 40 |
| 이순신 | 점수 | 90 |
| 강감찬 | 나이 | 50 |
| 강감찬 | 점수 | 100 |
원래는 한 행에 있던 여러 컬럼들이
각각 따로 행(row)으로 내려왔어.
.unstack()"행(index)을 열(columns)로 올리기"
행을 넓은 형태로 펼쳐서
넓고 짧은(wide format) 테이블로 바꾼다.
df.unstack()
df2 = df.set_index('이름')
df2.stack().unstack()
결과:
| 이름 | 나이 | 점수 |
|---|---|---|
| 홍길동 | 30 | 80 |
| 이순신 | 40 | 90 |
| 강감찬 | 50 | 100 |
다시 원래 형태로 복구!
| 메서드 | 핵심 기능 | 쉽게 말하면 |
|---|---|---|
set_index() | 컬럼을 인덱스로 | "이거 기준으로 정렬할게" |
reset_index() | 인덱스를 컬럼으로 복구 | "인덱스 풀고 다시 평평하게" |
stack() | 열을 행으로 | "가로 → 세로" 좁게 세우기 |
unstack() | 행을 열로 | "세로 → 가로" 넓게 펼치기 |
set_index() : 기준을 세운다 (정리 기준)
reset_index() : 기준을 풀고 그냥 컬럼으로
stack() : 데이터를 세워서 (길게)
unstack() : 데이터를 눕혀서 (넓게)
set_index/reset_index는 "어떤 컬럼을 인덱스로 쓸지" 정하는 거고,
stack/unstack은 "행과 열을 변환해서" 데이터를 세우거나 눕히는 거다!
df.groupby('성별')['점수'].agg(['mean', 'count', 'max'])transform() 사용df['성별'].value_counts(normalize=True) # 비율
pd.crosstab(df['성별'], df['학년'], normalize='index') # 행비율df.groupby('성별')['점수'].mean().sort_values(ascending=False)
| 옵션 | 뜻 |
|---|---|
ascending=True (기본값) | 오름차순 정렬 (작은 값 → 큰 값) |
ascending=False | 내림차순 정렬 (큰 값 → 작은 값) |
import pandas as pd
df = pd.DataFrame({
'성별': ['남', '여', '여', '남', '여'],
'점수': [80, 90, 75, 85, 95],
'학년': [1, 2, 1, 3, 2]
})
# 1. 전체 평균
print(df['점수'].mean())
# 2. 성별별 평균
print(df.groupby('성별')['점수'].mean())
# 3. 성별/학년별 평균
print(df.groupby(['성별', '학년'])['점수'].mean())
# 4. 여러 집계함수
print(df.groupby('성별').agg({'점수':['mean','max','min'], '학년':'count'}))
# 5. 성별별 점수 합계로 새 컬럼
df['성별합계'] = df.groupby('성별')['점수'].transform('sum')
print(df)
# 6. 피벗테이블로 요약
print(pd.pivot_table(df, index='성별', columns='학년', values='점수', aggfunc='mean', fill_value=0))
# 7. 교차표(빈도)
print(pd.crosstab(df['성별'], df['학년']))
| 함수/메서드 | 주요 옵션/역할 | 실무 활용 예시 |
|---|---|---|
groupby() | 그룹 기준, as_index, dropna | 분류/집계/그룹별 분석 |
agg() | 여러 집계함수, 컬럼별 다르게 | 복합 집계 통계 |
transform() | 그룹 집계값을 원본 크기로 | 새 컬럼에 그룹 기준값 매핑 |
apply() | 그룹별 임의 함수 적용 | 복잡한 커스텀 통계 |
filter() | 그룹 기준 조건 필터링 | 그룹 조건에 따라 행 전체 걸러내기 |
pivot_table() | index, columns, values, aggfunc, fill_value | 다차원 피벗/집계/결측치 보완 |
crosstab() | index, columns, normalize | 범주형 빈도, 비율 |
reset_index() | 인덱스 → 컬럼 | MultiIndex 해제, 후처리 |