pandas 학습 10단계 통합본 · 출력 결과 산출 서술형 문항

각 단계의 통합 코드를 읽고, 실행 결과를 직접 서술하는 평가용 HTML입니다.
학생 정보
※ pandas 버전, 표 출력 공백, 날짜 resample 표기는 실행 환경에 따라 조금 다를 수 있습니다. 핵심 값 중심으로 채점합니다.
서술형 1

1단계 pandas 기초: Series와 DataFrame 생성

문항: 아래 코드를 실행했을 때, 예시 2~10에서 출력되는 Series/DataFrame/columns/index/values/dtypes의 핵심 결과를 순서대로 서술하시오.
# 예시 1. pandas 불러오기와 버전 확인
import pandas as pd

print(pd.__version__)

# 예시 2. 리스트로 Series 만들기

s = pd.Series([10, 20, 30])
print(s)

# 예시 3. 인덱스가 있는 Series

s = pd.Series([90, 85, 100], index=['국어', '영어', '수학'])
print(s)

# 예시 4. 딕셔너리로 Series 만들기

s = pd.Series({'민수': 90, '지아': 95, '하준': 88})
print(s)

# 예시 5. 딕셔너리로 DataFrame 만들기

df = pd.DataFrame({
    '이름': ['민수', '지아', '하준'],
    '점수': [90, 95, 88]
})
print(df)

# 예시 6. 리스트 안의 딕셔너리로 DataFrame 만들기

data = [
    {'이름': '민수', '점수': 90},
    {'이름': '지아', '점수': 95},
    {'이름': '하준', '점수': 88}
]
df = pd.DataFrame(data)
print(df)

# 예시 7. 열 이름 확인

df = pd.DataFrame({'이름': ['민수', '지아'], '점수': [90, 95]})
print(df.columns)

# 예시 8. 인덱스 확인

df = pd.DataFrame({'이름': ['민수', '지아'], '점수': [90, 95]})
print(df.index)

# 예시 9. 값만 확인

df = pd.DataFrame({'이름': ['민수', '지아'], '점수': [90, 95]})
print(df.values)

# 예시 10. 자료형 확인

df = pd.DataFrame({'이름': ['민수', '지아'], '점수': [90, 95]})
print(df.dtypes)
예시 정답 및 풀이
pandas 버전이 먼저 출력된다. Series [10,20,30]은 기본 인덱스 0,1,2와 함께 출력된다. 국어 90, 영어 85, 수학 100 Series가 출력된다. 민수 90, 지아 95, 하준 88 Series가 출력된다. DataFrame은 이름과 점수 열을 가진 3행 표로 출력된다. columns는 Index(['이름','점수'], dtype='object'), index는 RangeIndex(start=0, stop=2, step=1), values는 [['민수',90],['지아',95]], dtypes는 이름 object, 점수 int64이다.
서술형 2

2단계 데이터 확인: head, tail, info, describe

문항: 아래 코드를 실행했을 때 head(), tail(), shape, info(), describe(), mean(), max/min, unique(), value_counts()가 각각 어떤 결과를 출력하는지 서술하시오.
# 예시 1. 앞부분 확인
import pandas as pd

df = pd.DataFrame({'번호': range(1, 11), '점수': [80,82,85,90,88,76,95,91,84,89]})
print(df.head())

# 예시 2. 앞부분 3행 확인

df = pd.DataFrame({'번호': range(1, 11), '점수': [80,82,85,90,88,76,95,91,84,89]})
print(df.head(3))

# 예시 3. 뒷부분 확인

df = pd.DataFrame({'번호': range(1, 11), '점수': [80,82,85,90,88,76,95,91,84,89]})
print(df.tail())

# 예시 4. 행과 열 개수 확인

df = pd.DataFrame({'이름':['민수','지아','하준'], '점수':[90,95,88]})
print(df.shape)

# 예시 5. 전체 정보 확인

df = pd.DataFrame({'이름':['민수','지아','하준'], '점수':[90,95,88]})
df.info()

# 예시 6. 기초 통계량 확인

df = pd.DataFrame({'점수':[90,95,88,76,100]})
print(df.describe())

# 예시 7. 열별 평균

df = pd.DataFrame({'국어':[90,80,70], '수학':[100,95,85]})
print(df.mean(numeric_only=True))

# 예시 8. 최댓값과 최솟값

df = pd.DataFrame({'점수':[90,95,88,76,100]})
print(df['점수'].max())
print(df['점수'].min())

# 예시 9. 고유값 확인

df = pd.DataFrame({'반':['1반','1반','2반','2반','3반']})
print(df['반'].unique())

# 예시 10. 값 개수 세기

df = pd.DataFrame({'반':['1반','1반','2반','2반','3반']})
print(df['반'].value_counts())
예시 정답 및 풀이
head()는 처음 5행, head(3)은 처음 3행, tail()은 마지막 5행을 보여준다. shape는 (3, 2)이다. info()는 열 이름, 결측치가 아닌 값 개수, 자료형을 보여준다. describe()는 count, mean, std, min, 사분위수, max를 출력한다. 국어 평균은 80.0, 수학 평균은 약 93.33이다. 점수 최댓값은 100, 최솟값은 76이다. unique()는 1반, 2반, 3반을 출력하고 value_counts()는 1반 2개, 2반 2개, 3반 1개를 출력한다.
서술형 3

3단계 데이터 선택: 열, 행, 조건 검색

문항: 아래 코드를 실행했을 때 선택되는 행과 열, 조건에 의해 남는 데이터가 무엇인지 순서대로 서술하시오.
# 예시 1. 한 열 선택
import pandas as pd

df = pd.DataFrame({'이름':['민수','지아','하준'], '점수':[90,95,88]})
print(df['이름'])

# 예시 2. 여러 열 선택

df = pd.DataFrame({'이름':['민수','지아','하준'], '국어':[90,95,88], '수학':[80,100,92]})
print(df[['이름', '수학']])

# 예시 3. iloc로 첫 행 선택

df = pd.DataFrame({'이름':['민수','지아','하준'], '점수':[90,95,88]})
print(df.iloc[0])

# 예시 4. iloc로 행 범위 선택

df = pd.DataFrame({'이름':['민수','지아','하준','서연'], '점수':[90,95,88,91]})
print(df.iloc[1:3])

# 예시 5. loc로 조건 없이 행 선택

df = pd.DataFrame({'이름':['민수','지아','하준'], '점수':[90,95,88]}, index=['a','b','c'])
print(df.loc['b'])

# 예시 6. loc로 행과 열 선택

df = pd.DataFrame({'이름':['민수','지아','하준'], '점수':[90,95,88]}, index=['a','b','c'])
print(df.loc['b', '점수'])

# 예시 7. 조건으로 행 선택

df = pd.DataFrame({'이름':['민수','지아','하준'], '점수':[90,95,88]})
print(df[df['점수'] >= 90])

# 예시 8. 조건과 열 선택 결합

df = pd.DataFrame({'이름':['민수','지아','하준'], '점수':[90,95,88]})
print(df.loc[df['점수'] >= 90, ['이름', '점수']])

# 예시 9. 문자열 조건 선택

df = pd.DataFrame({'이름':['김민수','이지아','김하준'], '점수':[90,95,88]})
print(df[df['이름'].str.startswith('김')])

# 예시 10. isin으로 여러 값 선택

df = pd.DataFrame({'반':['1반','2반','3반','1반'], '점수':[90,95,88,91]})
print(df[df['반'].isin(['1반', '3반'])])
예시 정답 및 풀이
이름 열만 선택하면 민수, 지아, 하준이 Series로 출력된다. 여러 열 선택은 이름과 수학 열만 표로 출력된다. iloc[0]은 첫 번째 행 민수 90을 출력한다. iloc[1:3]은 지아와 하준 행을 출력한다. loc['b']는 지아 95를 출력하고 loc['b','점수']는 95를 출력한다. 점수 90 이상 조건은 민수와 지아, 이름이 김으로 시작하는 조건은 김민수와 김하준, isin 조건은 1반과 3반 행만 남긴다.
서술형 4

4단계 데이터 수정: 열 추가, 값 수정, 행·열 삭제

문항: 아래 코드를 실행했을 때 새로 만들어지는 열, 수정되는 값, 삭제되는 행·열의 결과를 순서대로 서술하시오.
# 예시 1. 새 열 추가
import pandas as pd

df = pd.DataFrame({'이름':['민수','지아'], '점수':[90,95]})
df['합격'] = True
print(df)

# 예시 2. 계산 열 추가

df = pd.DataFrame({'국어':[90,80], '수학':[100,95]})
df['합계'] = df['국어'] + df['수학']
print(df)

# 예시 3. 평균 열 추가

df = pd.DataFrame({'국어':[90,80], '수학':[100,95]})
df['평균'] = df[['국어', '수학']].mean(axis=1)
print(df)

# 예시 4. 조건에 따라 값 만들기

df = pd.DataFrame({'이름':['민수','지아','하준'], '점수':[90,70,85]})
df['결과'] = df['점수'].apply(lambda x: '합격' if x >= 80 else '불합격')
print(df)

# 예시 5. 특정 값 수정

df = pd.DataFrame({'이름':['민수','지아'], '점수':[90,95]})
df.loc[0, '점수'] = 100
print(df)

# 예시 6. 조건에 맞는 값 수정

df = pd.DataFrame({'이름':['민수','지아','하준'], '점수':[90,70,85]})
df.loc[df['점수'] < 80, '보충'] = '필요'
print(df)

# 예시 7. 행 추가

df = pd.DataFrame({'이름':['민수','지아'], '점수':[90,95]})
df.loc[len(df)] = ['하준', 88]
print(df)

# 예시 8. 열 이름 변경

df = pd.DataFrame({'name':['민수','지아'], 'score':[90,95]})
df = df.rename(columns={'name':'이름', 'score':'점수'})
print(df)

# 예시 9. 열 삭제

df = pd.DataFrame({'이름':['민수','지아'], '점수':[90,95], '임시':[1,2]})
df = df.drop(columns=['임시'])
print(df)

# 예시 10. 행 삭제

df = pd.DataFrame({'이름':['민수','지아','하준'], '점수':[90,95,88]})
df = df.drop(index=[1])
print(df)
예시 정답 및 풀이
합격 열이 True로 추가된다. 국어+수학으로 합계 열이 생긴다. 평균 열에는 95.0, 87.5가 들어간다. 점수 80 이상은 합격, 80 미만은 불합격으로 결과 열이 생긴다. loc[0,'점수']=100으로 민수 점수가 100이 된다. 점수 80 미만인 지아에게 보충=필요가 들어가고 나머지는 NaN이다. 하준 행이 추가된다. name/score 열은 이름/점수로 바뀐다. 임시 열은 삭제되고, index 1 행인 지아가 삭제된다.
서술형 5

5단계 결측치와 중복 처리

문항: 아래 코드를 실행했을 때 결측치 확인, 결측치 처리, 중복 확인·제거 결과를 순서대로 서술하시오.
# 예시 1. 결측치 확인
import pandas as pd

df = pd.DataFrame({'이름':['민수','지아','하준'], '점수':[90, None, 88]})
print(df.isna())

# 예시 2. 열별 결측치 개수

df = pd.DataFrame({'이름':['민수','지아','하준'], '점수':[90, None, 88]})
print(df.isna().sum())

# 예시 3. 결측치가 있는 행 삭제

df = pd.DataFrame({'이름':['민수','지아','하준'], '점수':[90, None, 88]})
print(df.dropna())

# 예시 4. 결측치를 0으로 채우기

df = pd.DataFrame({'이름':['민수','지아','하준'], '점수':[90, None, 88]})
df['점수'] = df['점수'].fillna(0)
print(df)

# 예시 5. 평균으로 결측치 채우기

df = pd.DataFrame({'점수':[90, None, 88, 100]})
df['점수'] = df['점수'].fillna(df['점수'].mean())
print(df)

# 예시 6. 문자 결측치 채우기

df = pd.DataFrame({'이름':['민수', None, '하준'], '점수':[90,95,88]})
df['이름'] = df['이름'].fillna('이름없음')
print(df)

# 예시 7. 중복 행 확인

df = pd.DataFrame({'이름':['민수','민수','지아'], '점수':[90,90,95]})
print(df.duplicated())

# 예시 8. 중복 행 제거

df = pd.DataFrame({'이름':['민수','민수','지아'], '점수':[90,90,95]})
print(df.drop_duplicates())

# 예시 9. 특정 열 기준 중복 제거

df = pd.DataFrame({'이름':['민수','민수','지아'], '점수':[90,85,95]})
print(df.drop_duplicates(subset=['이름']))

# 예시 10. 인덱스 다시 정리

df = pd.DataFrame({'이름':['민수','민수','지아'], '점수':[90,90,95]})
df = df.drop_duplicates().reset_index(drop=True)
print(df)
예시 정답 및 풀이
isna()는 점수가 None인 지아 행만 True로 표시한다. isna().sum()은 이름 0, 점수 1을 출력한다. dropna()는 결측치가 있는 지아 행을 제거한다. fillna(0)은 지아 점수를 0으로 채운다. 평균 채우기는 None을 92.666...으로 채운다. 문자 결측치는 이름없음으로 채운다. duplicated()는 두 번째 민수 행만 True이다. drop_duplicates()는 완전 중복 행을 제거한다. subset=['이름'] 기준 중복 제거는 첫 번째 민수만 남긴다. reset_index(drop=True)는 인덱스를 0부터 다시 정리한다.
서술형 6

6단계 정렬과 순위

문항: 아래 코드를 실행했을 때 오름차순·내림차순 정렬 결과, 순위, 상위·하위 데이터가 어떻게 나오는지 서술하시오.
# 예시 1. 점수 오름차순 정렬
import pandas as pd

df = pd.DataFrame({'이름':['민수','지아','하준'], '점수':[90,95,88]})
print(df.sort_values('점수'))

# 예시 2. 점수 내림차순 정렬

df = pd.DataFrame({'이름':['민수','지아','하준'], '점수':[90,95,88]})
print(df.sort_values('점수', ascending=False))

# 예시 3. 여러 열 기준 정렬

df = pd.DataFrame({'반':['1반','1반','2반','2반'], '점수':[90,95,88,91]})
print(df.sort_values(['반', '점수'], ascending=[True, False]))

# 예시 4. 인덱스 기준 정렬

df = pd.DataFrame({'점수':[90,95,88]}, index=['c','a','b'])
print(df.sort_index())

# 예시 5. 정렬 후 인덱스 초기화

df = pd.DataFrame({'이름':['민수','지아','하준'], '점수':[90,95,88]})
result = df.sort_values('점수', ascending=False).reset_index(drop=True)
print(result)

# 예시 6. 순위 매기기

df = pd.DataFrame({'이름':['민수','지아','하준'], '점수':[90,95,88]})
df['순위'] = df['점수'].rank(ascending=False)
print(df)

# 예시 7. 정수 순위

df = pd.DataFrame({'이름':['민수','지아','하준'], '점수':[90,95,88]})
df['순위'] = df['점수'].rank(ascending=False).astype(int)
print(df)

# 예시 8. 동점 처리 방식

df = pd.DataFrame({'이름':['민수','지아','하준'], '점수':[90,90,80]})
df['순위'] = df['점수'].rank(ascending=False, method='min')
print(df)

# 예시 9. 상위 3개

df = pd.DataFrame({'이름':['민수','지아','하준','서연'], '점수':[90,95,88,91]})
print(df.nlargest(3, '점수'))

# 예시 10. 하위 2개

df = pd.DataFrame({'이름':['민수','지아','하준','서연'], '점수':[90,95,88,91]})
print(df.nsmallest(2, '점수'))
예시 정답 및 풀이
점수 오름차순은 하준 88, 민수 90, 지아 95 순서이다. 내림차순은 지아 95, 민수 90, 하준 88 순서이다. 여러 열 기준 정렬은 반은 오름차순, 점수는 반 안에서 내림차순이다. sort_index()는 a,b,c 순서로 정렬한다. reset_index(drop=True)는 정렬 후 인덱스를 0,1,2로 바꾼다. rank(ascending=False)는 지아 1, 민수 2, 하준 3이다. 동점 method='min'에서는 90점 두 명이 공동 1위, 80점은 3위이다. nlargest(3)은 지아, 서연, 민수이고 nsmallest(2)는 하준, 민수이다.
서술형 7

7단계 그룹화와 집계

문항: 아래 코드를 실행했을 때 반별 평균·합계·인원수·여러 통계·최고 학생 결과를 서술하시오.
# 예시 1. 반별 평균
import pandas as pd

df = pd.DataFrame({'반':['1반','1반','2반','2반'], '점수':[90,80,95,85]})
print(df.groupby('반')['점수'].mean())

# 예시 2. 반별 합계

df = pd.DataFrame({'반':['1반','1반','2반','2반'], '점수':[90,80,95,85]})
print(df.groupby('반')['점수'].sum())

# 예시 3. 반별 인원수

df = pd.DataFrame({'반':['1반','1반','2반','2반','2반'], '점수':[90,80,95,85,88]})
print(df.groupby('반')['점수'].count())

# 예시 4. 여러 통계 한 번에

df = pd.DataFrame({'반':['1반','1반','2반','2반'], '점수':[90,80,95,85]})
print(df.groupby('반')['점수'].agg(['mean', 'max', 'min']))

# 예시 5. 여러 열 집계

df = pd.DataFrame({'반':['1반','1반','2반','2반'], '국어':[90,80,95,85], '수학':[100,90,88,92]})
print(df.groupby('반')[['국어', '수학']].mean())

# 예시 6. 두 기준으로 그룹화

df = pd.DataFrame({'반':['1반','1반','2반','2반'], '성별':['남','여','남','여'], '점수':[90,80,95,85]})
print(df.groupby(['반', '성별'])['점수'].mean())

# 예시 7. 그룹 결과를 표로 변환

df = pd.DataFrame({'반':['1반','1반','2반','2반'], '점수':[90,80,95,85]})
result = df.groupby('반')['점수'].mean().reset_index()
print(result)

# 예시 8. 반별 최고 학생 찾기

df = pd.DataFrame({'반':['1반','1반','2반','2반'], '이름':['민수','지아','하준','서연'], '점수':[90,80,95,85]})
idx = df.groupby('반')['점수'].idxmax()
print(df.loc[idx])

# 예시 9. 조건 후 그룹화

df = pd.DataFrame({'반':['1반','1반','2반','2반'], '점수':[90,70,95,85]})
passed = df[df['점수'] >= 80]
print(passed.groupby('반')['점수'].count())

# 예시 10. 사용자 정의 집계

df = pd.DataFrame({'반':['1반','1반','2반','2반'], '점수':[90,80,95,85]})
print(df.groupby('반')['점수'].agg(lambda x: x.max() - x.min()))
예시 정답 및 풀이
반별 평균은 1반 85.0, 2반 90.0이다. 반별 합계는 1반 170, 2반 180이다. 반별 인원수는 1반 2명, 2반 3명이다. agg(['mean','max','min'])은 반별 평균·최댓값·최솟값을 표로 출력한다. 여러 열 집계는 반별 국어와 수학 평균을 출력한다. 두 기준 그룹화는 반과 성별 조합별 평균을 출력한다. reset_index()는 그룹 결과를 일반 표로 바꾼다. idxmax()는 1반 민수, 2반 하준을 최고 학생으로 찾는다. 합격 조건 후 그룹화는 1반 1명, 2반 2명을 출력한다. 사용자 정의 집계는 각 반의 점수 범위 10을 출력한다.
서술형 8

8단계 문자열과 날짜 처리

문항: 아래 코드를 실행했을 때 문자열 처리와 날짜 처리 결과가 어떻게 바뀌는지 서술하시오.
# 예시 1. 공백 제거
import pandas as pd

df = pd.DataFrame({'이름':[' 민수 ', ' 지아 ', '하준 ']})
df['이름'] = df['이름'].str.strip()
print(df)

# 예시 2. 소문자 변환

df = pd.DataFrame({'아이디':['KimA', 'LEE01', 'Park']})
df['아이디'] = df['아이디'].str.lower()
print(df)

# 예시 3. 문자 포함 여부

df = pd.DataFrame({'이름':['김민수','이지아','김하준']})
print(df[df['이름'].str.contains('김')])

# 예시 4. 문자열 분리

df = pd.DataFrame({'주소':['전북 전주', '서울 강남']})
df[['시도', '지역']] = df['주소'].str.split(' ', expand=True)
print(df)

# 예시 5. 문자열 치환

df = pd.DataFrame({'학교':['전북과학고', '전주고']})
df['학교'] = df['학교'].str.replace('고', '고등학교', regex=False)
print(df)

# 예시 6. 날짜 문자열 변환

df = pd.DataFrame({'날짜':['2026-06-01', '2026-06-02']})
df['날짜'] = pd.to_datetime(df['날짜'])
print(df.dtypes)

# 예시 7. 연도 추출

df = pd.DataFrame({'날짜': pd.to_datetime(['2026-06-01', '2025-12-31'])})
df['연도'] = df['날짜'].dt.year
print(df)

# 예시 8. 월과 일 추출

df = pd.DataFrame({'날짜': pd.to_datetime(['2026-06-01', '2026-06-02'])})
df['월'] = df['날짜'].dt.month
df['일'] = df['날짜'].dt.day
print(df)

# 예시 9. 요일 추출

df = pd.DataFrame({'날짜': pd.to_datetime(['2026-06-01', '2026-06-02'])})
df['요일번호'] = df['날짜'].dt.dayofweek
print(df)

# 예시 10. 날짜 차이 계산

df = pd.DataFrame({'시작': pd.to_datetime(['2026-06-01']), '끝': pd.to_datetime(['2026-06-10'])})
df['기간'] = (df['끝'] - df['시작']).dt.days
print(df)
예시 정답 및 풀이
str.strip()은 이름 앞뒤 공백을 제거한다. str.lower()는 아이디를 모두 소문자로 바꾼다. contains('김')은 김민수와 김하준 행을 남긴다. split(expand=True)는 주소를 시도와 지역 열로 나눈다. replace()는 고를 고등학교로 바꾼다. to_datetime() 후 날짜 열의 자료형은 datetime64이다. dt.year는 2026, 2025를 추출한다. dt.month와 dt.day는 월·일을 만든다. dayofweek는 월요일 0, 화요일 1로 출력된다. 날짜 차이는 9일이다.
서술형 9

9단계 파일 입출력과 데이터 병합

문항: 아래 코드를 실행했을 때 CSV/Excel 저장·읽기, concat, merge 결과가 어떻게 출력되는지 서술하시오.
# 예시 1. CSV 저장
import pandas as pd

df = pd.DataFrame({'이름':['민수','지아'], '점수':[90,95]})
df.to_csv('score.csv', index=False, encoding='utf-8-sig')
print('저장 완료')

# 예시 2. CSV 읽기

df = pd.read_csv('score.csv')
print(df)

# 예시 3. Excel 저장

df = pd.DataFrame({'이름':['민수','지아'], '점수':[90,95]})
df.to_excel('score.xlsx', index=False)
print('엑셀 저장 완료')

# 예시 4. Excel 읽기

df = pd.read_excel('score.xlsx')
print(df)

# 예시 5. 세로 방향 합치기

df1 = pd.DataFrame({'이름':['민수'], '점수':[90]})
df2 = pd.DataFrame({'이름':['지아'], '점수':[95]})
result = pd.concat([df1, df2], ignore_index=True)
print(result)

# 예시 6. 가로 방향 합치기

df1 = pd.DataFrame({'이름':['민수','지아']})
df2 = pd.DataFrame({'점수':[90,95]})
result = pd.concat([df1, df2], axis=1)
print(result)

# 예시 7. 공통 열로 병합

score = pd.DataFrame({'이름':['민수','지아'], '점수':[90,95]})
club = pd.DataFrame({'이름':['민수','지아'], '동아리':['AI','로봇']})
result = pd.merge(score, club, on='이름')
print(result)

# 예시 8. 왼쪽 기준 병합

score = pd.DataFrame({'이름':['민수','지아','하준'], '점수':[90,95,88]})
club = pd.DataFrame({'이름':['민수','지아'], '동아리':['AI','로봇']})
result = pd.merge(score, club, on='이름', how='left')
print(result)

# 예시 9. 공통 행만 병합

a = pd.DataFrame({'이름':['민수','지아'], '국어':[90,95]})
b = pd.DataFrame({'이름':['지아','하준'], '수학':[100,88]})
print(pd.merge(a, b, on='이름', how='inner'))

# 예시 10. 전체 외부 병합

a = pd.DataFrame({'이름':['민수','지아'], '국어':[90,95]})
b = pd.DataFrame({'이름':['지아','하준'], '수학':[100,88]})
print(pd.merge(a, b, on='이름', how='outer'))
예시 정답 및 풀이
score.csv 저장 후 저장 완료가 출력된다. read_csv는 민수 90, 지아 95 표를 읽어 출력한다. Excel 저장 후 엑셀 저장 완료가 출력되고 read_excel도 같은 표를 읽는다. 세로 concat은 민수와 지아가 행으로 이어진다. 가로 concat은 이름 열 옆에 점수 열이 붙는다. merge(on='이름')는 이름 기준으로 점수와 동아리를 결합한다. left merge는 하준의 동아리가 NaN으로 남는다. inner merge는 공통 이름 지아만 남는다. outer merge는 민수, 지아, 하준 전체가 남고 없는 값은 NaN이다.
서술형 10

10단계 심화 분석: 피벗, 구간화, 상관, 시계열

문항: 아래 코드를 실행했을 때 피벗 테이블, 등급 구간, 상관계수, 시계열, 이동평균, query/eval 결과를 서술하시오.
# 예시 1. 피벗 테이블 평균
import pandas as pd

df = pd.DataFrame({'반':['1반','1반','2반','2반'], '과목':['국어','수학','국어','수학'], '점수':[90,100,85,95]})
print(pd.pivot_table(df, values='점수', index='반', columns='과목', aggfunc='mean'))

# 예시 2. 피벗 테이블 합계

df = pd.DataFrame({'월':['1월','1월','2월','2월'], '품목':['A','B','A','B'], '매출':[100,150,120,170]})
print(pd.pivot_table(df, values='매출', index='월', columns='품목', aggfunc='sum'))

# 예시 3. 구간 나누기

df = pd.DataFrame({'점수':[55,68,75,84,92]})
df['등급'] = pd.cut(df['점수'], bins=[0,60,80,100], labels=['하','중','상'])
print(df)

# 예시 4. 상관계수

df = pd.DataFrame({'공부시간':[1,2,3,4,5], '점수':[60,65,75,85,90]})
print(df.corr(numeric_only=True))

# 예시 5. 시계열 인덱스 만들기

dates = pd.date_range('2026-06-01', periods=5)
df = pd.DataFrame({'방문자':[10,15,13,20,18]}, index=dates)
print(df)

# 예시 6. 월별 합계 resample

df = pd.DataFrame({'날짜': pd.to_datetime(['2026-01-01','2026-01-15','2026-02-01']), '매출':[100,200,300]})
df = df.set_index('날짜')
print(df.resample('ME').sum())

# 예시 7. 이동평균

df = pd.DataFrame({'점수':[70,80,90,85,95]})
df['이동평균'] = df['점수'].rolling(window=3).mean()
print(df)

# 예시 8. query로 조건 검색

df = pd.DataFrame({'이름':['민수','지아','하준'], '점수':[90,95,88]})
print(df.query('점수 >= 90'))

# 예시 9. eval로 계산식 적용

df = pd.DataFrame({'국어':[90,80], '수학':[100,95]})
df['합계'] = df.eval('국어 + 수학')
print(df)

# 예시 10. 분석 결과 저장까지

df = pd.DataFrame({'반':['1반','1반','2반','2반'], '점수':[90,80,95,85]})
summary = df.groupby('반')['점수'].agg(['mean', 'max', 'min']).reset_index()
summary.to_csv('summary.csv', index=False, encoding='utf-8-sig')
print(summary)
예시 정답 및 풀이
피벗 평균은 반을 행, 과목을 열로 하여 국어/수학 점수를 보여준다. 피벗 합계는 월별 품목 A/B 매출 합계를 보여준다. pd.cut은 55 하, 68 중, 75 중, 84 상, 92 상 등급을 만든다. corr()는 공부시간과 점수 사이의 양의 상관계수를 출력한다. date_range는 2026-06-01부터 5일간 날짜 인덱스를 만든다. resample('ME')는 1월 300, 2월 300 매출 합계를 만든다. rolling(3).mean()은 처음 두 행은 NaN, 이후 80.0, 85.0, 90.0이다. query는 민수와 지아를 남기고 eval은 합계 190, 175를 만든다. 마지막 summary는 반별 mean, max, min 표를 저장하고 출력한다.