본문 바로가기
두두 IT/파이썬

[PYTHON-Pandas 03-01] 데이터 정렬부터 그룹화, 피벗 테이블

by DoDo's 2026. 5. 4.
반응형

🐼 [Pandas 복습 노트 2탄] 데이터 정렬부터 그룹화, 피벗 테이블까지 완벽 마스터!

데이터프레임을 만들고 원하는 데이터를 뽑아내는 방법을 익히셨다면, 이제 데이터를 '요리'할 차례입니다.

오늘은 데이터를 순서대로 정렬하고, 통계를 내고, 그룹별로 묶어 분석하는 판다스의 고급 기술들을 블로그 형태로 아주 쉽게 정리해 드릴게요! 🚀


🔢 1. 데이터 줄세우기 (정렬: Sorting)

데이터를 볼 때 가장 먼저 하는 일은 가나다순, 혹은 크기순으로 줄을 세우는 일이죠. 판다스에서는 기준이 이름표(Index/Column)인지, 실제 데이터 값(Value)인지에 따라 두 가지 메서드를 사용합니다.

 

① 이름표 기준으로 정렬: sort_index()

  • 역할: 행 이름(index)이나 열 이름(column)을 기준으로 알파벳/가나다순 정렬을 합니다.
  • 주요 파라미터:
    • axis: 0 또는 'index'면 행 이름 기준(기본값), 1 또는 'columns'면 열 이름 기준입니다.
    • ascending: True면 오름차순(기본값), False면 내림차순입니다.
    • inplace: True를 주면 원본 데이터가 바로 변경됩니다.
  • 💡 꿀팁: 행 이름을 정렬해 두면, df.loc['A':'C']처럼 앞글자만 이용해 슬라이싱(범위 자르기)을 할 수 있습니다. (단, 인덱스 이름에 결측치가 있으면 안 됩니다!)

② 데이터 값 기준으로 정렬: sort_values()

  • 역할: 특정 열(컬럼) 안에 들어있는 실제 데이터를 기준으로 정렬합니다. (엑셀의 데이터 정렬과 동일)
  • 주요 파라미터:
    • by: 정렬의 기준이 될 컬럼 이름을 문자열로 적어줍니다. 여러 개를 기준으로 삼으려면 리스트로 묶어줍니다. (예: by=["나이", "연봉"])
  • 💡 주의점: 오름차순, 내림차순 상관없이 결측치(NaN)는 무조건 맨 마지막으로 밀려납니다.

📊 2. 데이터 요약하기 (기술통계와 agg)

데이터의 평균, 최대값 등을 구하는 것은 기본 중의 기본입니다. 판다스는 sum()(합계), mean()(평균), median()(중위수), std()(표준편차), min(), max(), count()(결측치 제외 개수) 등 다양한 기술 통계 메서드를 제공합니다. 문자열 데이터의 경우 최빈값이나 고유값 개수 등도 켤 수 있습니다.

  • 공통 파라미터 skipna: 기본값은 True입니다. 빈칸(결측치)을 무시하고 계산하겠다는 뜻이죠. 만약 False로 바꾸면, 데이터 중 하나라도 결측치가 있을 때 결과값 자체가 결측치(NaN)로 나와버리니 주의하세요!
  • 공통 파라미터 numeric_only: 수치형(정수, 실수) 컬럼만 연산할 때 True로 설정합니다.

🎯 한 번에 여러 통계값 보기: agg() / aggregate()

 

"평균도 보고 싶고, 합계도 보고 싶고, 최대값도 보고 싶어!" 할 때 씁니다.

Python
 
# 'AIR_TIME' 컬럼의 최소, 최대값을 한번에 조회
df['AIR_TIME'].agg(["min", "max"]) #

# 컬럼별로 다른 통계 구하기 (딕셔너리 활용)
df.agg({'DEP_DELAY': 'mean', 'ARR_DELAY': 'max'}) #

내가 직접 만든 함수(사용자 정의 함수)를 agg() 안에 넣어서 계산할 수도 있습니다!

 

묶어서 분석하기! (Groupby)

데이터 분석에서 가장 중요한 개념 중 하나입니다. 성별, 직급별, 지역별 등 특정 항목(범주형 데이터)을 기준으로 데이터를 묶어서 집계할 때 사용합니다.

① groupby() 기본 구조

데이터프레임.groupby('기준컬럼')['계산할컬럼'].집계함수()

Python
 
# 항공사별(AIRLINE)로 묶어서, 취소건수(CANCELLED)의 합계(sum) 구하기
df.groupby("AIRLINE")['CANCELLED'].sum() #

② 여러 기준으로 묶기

기준 컬럼이 여러 개라면 리스트 [ ]로 묶어주면 됩니다.

Python
 
# 항공사(AIRLINE)와 출발공항(ORG_AIR) 두 가지 기준으로 묶기
df.groupby(["AIRLINE", "ORG_AIR"])['CANCELLED'].sum() #

🧮 4. 한눈에 보기 편한 표 만들기 (pivot_table)

groupby로 여러 컬럼을 묶으면 결과가 세로로 길게 나와서 보기 불편할 때가 있습니다. 이때 엑셀의 피벗 테이블처럼 가독성 좋게 만들어주는 메서드가 바로 pivot_table()입니다.

  • index: 행(가로줄)으로 보낼 기준 컬럼
  • columns: 열(세로줄)로 보낼 기준 컬럼
  • values: 계산(집계)할 데이터 컬럼
  • aggfunc: 어떤 계산을 할지 (기본값은 mean 평균입니다!)
  • fill_value: 계산 결과가 결측치(NA)일 때 대신 채워 넣을 값
Python
 
# 월별(index), 항공사/출발공항별(columns) 취소건수(values) 합계(sum)
df.pivot_table(index="MONTH", columns=["AIRLINE", "ORG_AIR"], values="CANCELLED", aggfunc="sum") #

✂️ 5. 숫자를 그룹으로 자르기 (cut)

나이 데이터(17, 23, 45, 50...)를 "유아, 청소년, 청년, 장년"처럼 그룹(범주형)으로 바꾸고 싶을 때 pd.cut()을 사용합니다.

  • x: 자를 데이터 (예: df['age'])
  • bins: 자를 기준점 리스트 (예: [1, 5, 20, 40, 50, 100])
  • labels: 나눠진 구역에 붙일 이름표
  • right: 오른쪽 경계값을 포함할지(True, 기본값) 왼쪽을 포함할지(False) 결정합니다.

💡 기호 상식: (100, 200]은 수학에서 100은 포함하지 않고(초과), 200은 포함한다(이하)는 뜻입니다.

 

🚀 6. 반복문 없이 일괄 처리! (apply)

데이터의 모든 원소나 행/열 단위로 똑같은 작업을 반복해야 할 때, 파이썬의 for문 대신 apply()를 쓰면 훨씬 빠르고 세련되게 코딩할 수 있습니다.

  • Series(하나의 열)에 적용: 원소 하나하나에 함수가 차례대로 적용됩니다.
  • DataFrame에 적용:
    • axis=0 (기본값): 열(컬럼) 단위로 함수가 통째로 들어갑니다.
    • axis=1: 행(로우) 단위로 함수가 통째로 들어갑니다.
Python
 
# 요일 숫자(1~7)를 한글 요일 문자열로 바꾸는 일괄 처리 예시
df['WEEKDAY'].apply(lambda x: "월화수목금토일"[x-1] + "요일") #

📝 [실습 TODO] 실력 쑥쑥 확인 문제!

눈으로만 보면 금방 까먹습니다! 배운 내용을 바탕으로 퀴즈와 실습 코드를 직접 풀어보세요.

📌 [객관식 문제]

Q1. df.sort_values(by='score') 코드를 실행했을 때, 'score' 컬럼에 있는 결측치(NaN)는 어디에 정렬될까요?

  1. 맨 처음에 위치한다.
  2. 무작위 위치에 들어간다.
  3. 에러가 발생하며 정렬되지 않는다.
  4. 오름차순/내림차순 상관없이 무조건 맨 마지막에 위치한다.

Q2. 통계 메서드를 사용할 때 skipna=True 파라미터가 의미하는 것은 무엇인가요?

  1. 결측치를 모두 0으로 바꾸어 계산한다.
  2. 결측치를 무시(제외)하고 나머지 값들로만 계산한다.
  3. 결측치가 하나라도 있으면 결과값을 무조건 결측치로 반환한다.
  4. 결측치가 있는 열 자체를 삭제한다.

Q3. '부서'별로 '연봉'의 '평균'을 구하려고 합니다. 올바른 groupby 문법은 무엇일까요?

  1. df.groupby('연봉')['부서'].mean()
  2. df.groupby('부서')['연봉'].mean()
  3. df.groupby('평균')['부서'].연봉()
  4. df.groupby('부서')['평균'].sum()

Q4. pivot_table에서 집계 함수를 지정하는 파라미터는 무엇인가요? (기본값은 'mean'입니다)

  1. aggregate
  2. function
  3. aggfunc
  4. method

Q5. pd.cut에서 범위가 (10, 20] 으로 표시되었습니다. 이 범위가 의미하는 올바른 해석은 무엇인가요?

  1. 10 이상 20 미만
  2. 10 초과 20 미만
  3. 10 초과 20 이하
  4. 10 이상 20 이하

💻 [주관식 / 코딩 문제]

(가상의 직원 데이터 df가 있다고 가정하고 코드를 작성해 보세요! 컬럼: '이름', '부서', '직급', '급여', '나이')

Q1. [정렬] df를 '나이' 컬럼을 기준으로 내림차순(나이가 많은 순서대로) 정렬하는 코드를 작성하세요.

Q2. [집계] df의 '급여' 컬럼에 대하여, '최소값(min)'과 '최대값(max)'을 동시에 확인하는 코드를 agg()를 활용하여 작성하세요.

Q3. [Groupby] '부서'와 '직급' 두 가지를 기준으로 그룹을 묶은 뒤, '급여'의 합계(sum)를 구하는 코드를 작성하세요.

Q4. [Pivot Table] '부서'를 행(index)으로, '직급'을 열(columns)로 배치하고, 안의 데이터(values)로는 '급여'의 평균을 보여주는 피벗 테이블 코드를 작성하세요. (집계함수 파라미터는 생략하지 말고 명시적으로 작성하세요.)

Q5. [Apply] '나이' 컬럼의 모든 값에 일괄적으로 1살씩 더하고 싶습니다. apply()와 익명함수 lambda x를 활용하여 코드를 작성하세요.



💡 [정답 확인란]

 

(직접 풀어본 후 아래를 드래그하여 정답을 확인하세요!)

[객관식 정답]

  1. 4번 (결측치는 방식 상관없이 마지막에 나옵니다.)
  2.  
  3. 2번 (기본값이며, 결측치를 무시하고 연산합니다.)
  4.  
  5. 2번 (그룹 묶을 기준: 부서, 계산할 대상: 연봉, 함수: mean())
  6.  
  7. 3번 (aggfunc)
  8.  
  9. 3번 (()는 불포함, []는 포함을 의미합니다.[cite: 2])

[주관식/코딩 정답]

  1. df.sort_values(by='나이', ascending=False)
  2. [cite: 2]
  3. df['급여'].agg(['min', 'max'])
  4. [cite: 2]
  5. df.groupby(['부서', '직급'])['급여'].sum()
  6. [cite: 2]
  7. df.pivot_table(index='부서', columns='직급', values='급여', aggfunc='mean')
  8. [cite: 2]
  9. df['나이'].apply(lambda x: x + 1)
  10. [cite: 2]
반응형