포스트

[Python 100일 챌린지] Day 63 - Pandas 기초

[Python 100일 챌린지] Day 63 - Pandas 기초

데이터 분석의 핵심, Pandas! 🐼

엑셀처럼 데이터를 다루고 싶으신가요? Pandas를 쓰면 수백만 행 데이터도 코드 몇 줄로 분석할 수 있어요! 데이터 과학자, 분석가들의 필수 도구를 오늘 배워봅시다! 💪

(30-40분 완독 ⭐⭐)

🎯 오늘의 학습 목표

📚 사전 지식


🎯 학습 목표 1: Pandas가 무엇인지 이해하기

한 줄 설명

Pandas = Python으로 엑셀 같은 표 데이터를 다루는 라이브러리 📊

1.1 Pandas가 필요한 이유

1
2
3
4
5
6
7
8
9
10
11
# ❌ 순수 Python으로 CSV 처리
data = []
with open('sales.csv', 'r') as f:
    for line in f:
        data.append(line.strip().split(','))
# 이후 복잡한 처리...

# ✅ Pandas로 CSV 처리
import pandas as pd
df = pd.read_csv('sales.csv')
print(df.head())  # 끝!

1.2 Pandas 설치하기

1
2
# Pandas 설치
pip install pandas

설치 확인:

1
python -c "import pandas as pd; print(f'Pandas {pd.__version__} 설치 완료!')"

1.3 Pandas의 두 가지 핵심 구조

1
2
3
4
import pandas as pd

# 1. Series: 1차원 데이터 (엑셀의 한 열)
# 2. DataFrame: 2차원 데이터 (엑셀 시트 전체)

💡 Series와 DataFrame을 비유하면?

구조 비유 설명
Series 엑셀 한 열 학생들의 “점수”만 모아놓은 것
DataFrame 엑셀 시트 전체 이름, 나이, 점수… 여러 열이 합쳐진 표

즉, DataFrame = 여러 개의 Series를 옆으로 붙인 것이에요!

graph LR
    A[Pandas] --> B[Series<br/>1차원]
    A --> C[DataFrame<br/>2차원]
    B --> D["[10, 20, 30]"]
    C --> E["이름 | 나이 | 점수<br/>철수 | 20 | 85<br/>영희 | 22 | 90"]

🎯 학습 목표 2: Series 다루기

2.1 Series 만들기

💡 인덱스(index)란?

Series와 DataFrame에서 인덱스는 각 행에 붙는 이름표(라벨)예요!

  • 기본값: 0, 1, 2, 3… (숫자)
  • 직접 지정: ‘국어’, ‘영어’, ‘수학’… (문자열)

엑셀에서 행 번호(1, 2, 3…)가 인덱스라고 생각하면 돼요!

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
import pandas as pd

# 리스트로 만들기
s1 = pd.Series([10, 20, 30, 40])
print(s1)
# 0    10    ← 0은 인덱스, 10은 값
# 1    20
# 2    30
# 3    40
# dtype: int64  ← 데이터 타입 (64비트 정수)

# 인덱스 지정하기
s2 = pd.Series([85, 90, 78, 92],
               index=['국어', '영어', '수학', '과학'])
print(s2)
# 국어    85
# 영어    90
# 수학    78
# 과학    92
# dtype: int64

# 딕셔너리로 만들기
data = {'서울': 9700000, '부산': 3400000, '인천': 2900000}
s3 = pd.Series(data)
print(s3)

2.2 Series 인덱싱

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
import pandas as pd

scores = pd.Series([85, 90, 78, 92],
                   index=['국어', '영어', '수학', '과학'])

# 인덱스로 접근
print(scores['영어'])     # 90
print(scores[['국어', '수학']])  # 여러 개

# 숫자 위치로 접근
print(scores[0])          # 85
print(scores[1:3])        # 영어, 수학

# 조건 필터링
print(scores[scores >= 85])  # 85점 이상

2.3 Series 연산

1
2
3
4
5
6
7
8
9
10
11
12
13
14
import pandas as pd

s1 = pd.Series([10, 20, 30])
s2 = pd.Series([1, 2, 3])

# 기본 연산
print(s1 + s2)   # [11, 22, 33]
print(s1 * 2)    # [20, 40, 60]

# 통계 메서드
print(s1.sum())   # 60
print(s1.mean())  # 20.0
print(s1.max())   # 30
print(s1.min())   # 10

🎯 학습 목표 3: DataFrame 만들기

3.1 딕셔너리로 만들기

💡 DataFrame 만들기, 이렇게 기억하세요!

딕셔너리에서: 키 = 열 이름, 값(리스트) = 열 데이터

1
2
3
{'이름': ['철수', '영희'], '나이': [20, 22]}
                                  
  이름     데이터     이름    데이터
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
import pandas as pd

# 가장 흔한 방법! (딕셔너리 → DataFrame)
data = {
    '이름': ['철수', '영희', '민수', '지영'],  # 첫 번째 열
    '나이': [20, 22, 21, 23],                  # 두 번째 열
    '점수': [85, 90, 78, 92]                   # 세 번째 열
}

df = pd.DataFrame(data)
print(df)
#    이름  나이  점수   ← 열 이름 (딕셔너리의 키)
# 0  철수   20   85    ← 0, 1, 2, 3은 자동 생성된 인덱스
# 1  영희   22   90
# 2  민수   21   78
# 3  지영   23   92

3.2 리스트로 만들기

1
2
3
4
5
6
7
8
9
10
11
import pandas as pd

# 리스트의 리스트
data = [
    ['철수', 20, 85],
    ['영희', 22, 90],
    ['민수', 21, 78]
]

df = pd.DataFrame(data, columns=['이름', '나이', '점수'])
print(df)

3.3 인덱스 지정하기

1
2
3
4
5
6
7
8
9
10
11
12
13
14
import pandas as pd

data = {
    '국어': [85, 90, 78],
    '영어': [90, 85, 92],
    '수학': [88, 78, 85]
}

df = pd.DataFrame(data, index=['철수', '영희', '민수'])
print(df)
#      국어  영어  수학
# 철수   85   90   88
# 영희   90   85   78
# 민수   78   92   85

3.4 NumPy 배열로 만들기

1
2
3
4
5
6
7
8
9
10
11
import pandas as pd
import numpy as np

arr = np.array([[1, 2, 3],
                [4, 5, 6],
                [7, 8, 9]])

df = pd.DataFrame(arr,
                  columns=['A', 'B', 'C'],
                  index=['X', 'Y', 'Z'])
print(df)

🎯 학습 목표 4: DataFrame 기본 탐색하기

4.1 기본 정보 확인

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
import pandas as pd

df = pd.DataFrame({
    '이름': ['철수', '영희', '민수', '지영', '현수'],
    '나이': [20, 22, 21, 23, 20],
    '점수': [85, 90, 78, 92, 88],
    '학과': ['컴퓨터', '경영', '컴퓨터', '경영', '전자']
})

# 처음/끝 몇 행 보기
print(df.head())    # 처음 5행
print(df.head(3))   # 처음 3행
print(df.tail(2))   # 마지막 2행

# 크기 확인
print(df.shape)     # (5, 4) - 5행 4열

# 열 이름
print(df.columns)   # Index(['이름', '나이', '점수', '학과'], ...)

# 인덱스
print(df.index)     # RangeIndex(start=0, stop=5, step=1)

# 데이터 타입
print(df.dtypes)
# 이름    object
# 나이     int64
# 점수     int64
# 학과    object

4.2 info()와 describe()

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
import pandas as pd

df = pd.DataFrame({
    '이름': ['철수', '영희', '민수', '지영', '현수'],
    '나이': [20, 22, 21, 23, 20],
    '점수': [85, 90, 78, 92, 88]
})

# 전체 정보 요약
print(df.info())
# <class 'pandas.core.frame.DataFrame'>
# RangeIndex: 5 entries, 0 to 4
# Data columns (total 3 columns):
#  #   Column  Non-Null Count  Dtype
# ---  ------  --------------  -----
#  0   이름      5 non-null      object
#  1   나이      5 non-null      int64
#  2   점수      5 non-null      int64

# 수치형 열의 통계 요약
print(df.describe())
#              나이        점수
# count   5.000000   5.000000
# mean   21.200000  86.600000
# std     1.303840   5.176872
# min    20.000000  78.000000
# 25%    20.000000  85.000000
# 50%    21.000000  88.000000
# 75%    22.000000  90.000000
# max    23.000000  92.000000

4.3 열 선택하기

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
import pandas as pd

df = pd.DataFrame({
    '이름': ['철수', '영희', '민수'],
    '나이': [20, 22, 21],
    '점수': [85, 90, 78]
})

# 한 열 선택 (Series 반환)
print(df['이름'])
# 0    철수
# 1    영희
# 2    민수

# 여러 열 선택 (DataFrame 반환)
print(df[['이름', '점수']])
#    이름  점수
# 0  철수   85
# 1  영희   90
# 2  민수   78

# 점(.) 표기법 (열 이름이 영어일 때)
df2 = pd.DataFrame({'name': ['A', 'B'], 'age': [20, 30]})
print(df2.name)  # df2['name']과 동일

4.4 행 선택하기

💡 loc vs iloc 쉽게 기억하기!

메서드 의미 기억법
loc Label의 loc 이름(라벨)으로 찾기
iloc Integer의 iloc 숫자(위치)로 찾기

비유:

  • loc = 책을 제목으로 찾기 (“파이썬 책 주세요”)
  • iloc = 책을 위치로 찾기 (“3번째 칸에 있는 책 주세요”)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
import pandas as pd

df = pd.DataFrame({
    '이름': ['철수', '영희', '민수'],
    '나이': [20, 22, 21],
    '점수': [85, 90, 78]
})

# loc: 라벨(이름) 기반 - L은 Label!
print(df.loc[0])      # 인덱스가 0인 행
print(df.loc[0:1])    # 인덱스 0~1 (1 포함! ⭐ loc은 끝 포함)

# iloc: 위치(숫자) 기반 - I는 Integer!
print(df.iloc[0])     # 첫 번째 행
print(df.iloc[0:2])   # 0~1번째 행 (2 미포함 - 리스트/NumPy처럼)

# 특정 셀 선택
print(df.loc[0, '이름'])   # '철수' - 행 라벨, 열 이름
print(df.iloc[0, 0])       # '철수' - 행 위치, 열 위치

💡 실전 팁 & 주의사항

✅ 좋은 습관

1
2
3
4
5
6
7
8
9
10
11
import pandas as pd

# 1. pd로 임포트하기 (관례)
import pandas as pd  # ✅

# 2. 데이터 확인 습관
df = pd.read_csv('data.csv')
print(df.shape)      # 크기 확인
print(df.head())     # 내용 미리보기
print(df.info())     # 타입 확인
print(df.describe()) # 통계 확인

⚠️ loc vs iloc 슬라이싱 차이 (중요!)

1
2
3
4
5
6
7
8
9
10
11
import pandas as pd

df = pd.DataFrame({
    'A': [1, 2, 3]
}, index=['x', 'y', 'z'])

# loc: 라벨 기반 - 끝 포함! ⭐
print(df.loc['x':'y'])  # x, y 행 (y 포함!)

# iloc: 위치 기반 - 끝 미포함 (NumPy/리스트와 동일)
print(df.iloc[0:2])     # 0, 1번째 행 (2 미포함)

💡 기억하기: loc라벨이라 끝 포함, iloc인덱스라 NumPy처럼 끝 미포함!

⚠️ 점(.) 표기법 주의

1
2
3
4
5
6
7
8
9
10
11
import pandas as pd

df = pd.DataFrame({'name': ['A', 'B'], 'count': [10, 20]})

# ✅ 안전한 방법
print(df['name'])    # 항상 작동
print(df['count'])   # 항상 작동

# ⚠️ 점 표기법 주의
print(df.name)       # ✅ 작동
# print(df.count)    # ❌ 위험! count는 메서드 이름과 충돌

💡 권장: 열 이름이 메서드와 겹칠 수 있으니 df['열이름'] 형태를 사용하세요!


🧪 연습 문제

문제 1: 학생 데이터 만들기

5명 학생의 이름, 나이, 국어, 영어, 수학 점수가 담긴 DataFrame을 만들고, 각 과목의 평균을 출력하세요.

💡 힌트

단계별 접근:

  1. 딕셔너리 만들기: 키는 ‘이름’, ‘나이’, ‘국어’, ‘영어’, ‘수학’
  2. 값은 리스트: 각 5명의 데이터를 리스트로
  3. DataFrame 생성: pd.DataFrame(딕셔너리)
  4. 평균 계산: df['국어'].mean() 또는 df[['국어', '영어', '수학']].mean()
1
2
3
4
5
6
# 구조 예시
data = {
    '이름': ['학생1', '학생2', ...],
    '국어': [점수1, 점수2, ...],
    # ...
}
정답 코드
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
import pandas as pd

df = pd.DataFrame({
    '이름': ['철수', '영희', '민수', '지영', '현수'],
    '나이': [20, 22, 21, 23, 20],
    '국어': [85, 90, 78, 92, 88],
    '영어': [90, 85, 92, 88, 95],
    '수학': [78, 88, 85, 90, 82]
})

print(df)
print("\n=== 과목별 평균 ===")
print(f"국어 평균: {df['국어'].mean():.1f}")
print(f"영어 평균: {df['영어'].mean():.1f}")
print(f"수학 평균: {df['수학'].mean():.1f}")

문제 2: 조건에 맞는 데이터 찾기

위 DataFrame에서 국어 점수가 85점 이상인 학생들만 출력하세요.

💡 힌트

단계별 접근:

  1. 조건 만들기: df['국어'] >= 85
    • 이것만 실행하면 [True, True, False, True, True] 같은 불리언 Series가 나와요
  2. 필터링 적용: df[조건]
    • True인 행만 골라서 새로운 DataFrame으로!
1
2
3
4
5
6
# 조건 필터링 패턴
조건 = df['열이름'] >= 
결과 = df[조건]

# 또는 한 줄로:
결과 = df[df['열이름'] >= ]

💡 Day 62에서 배운 NumPy 불리언 인덱싱과 같은 원리예요!

정답 코드
1
2
3
4
5
6
7
8
9
10
import pandas as pd

df = pd.DataFrame({
    '이름': ['철수', '영희', '민수', '지영', '현수'],
    '국어': [85, 90, 78, 92, 88]
})

# 국어 85점 이상
high_scorers = df[df['국어'] >= 85]
print(high_scorers)

📝 오늘 배운 내용 정리

  1. Pandas = Python 데이터 분석 핵심 라이브러리
  2. Series: 1차원 데이터 (인덱스 + 값)
  3. DataFrame: 2차원 데이터 (엑셀 시트처럼)
  4. 기본 탐색: head(), info(), describe(), shape
  5. 선택: 열은 df['열'], 행은 df.loc[], df.iloc[]

🔗 관련 자료


📚 이전 학습

Day 62: NumPy 활용 ⭐⭐

어제는 NumPy 인덱싱, 슬라이싱, 브로드캐스팅을 배웠어요!

📚 다음 학습

Day 64: Pandas 데이터 로딩 ⭐⭐

내일은 CSV, Excel 파일을 읽고 쓰는 방법을 배워요!


“늦었다고 생각할 때가 가장 빠른 때입니다. 오늘도 한 걸음 성장했어요!” 🚀

Day 63/100 Phase 7: 데이터 분석 기초 #100DaysOfPython
이 기사는 저작권자의 CC BY 4.0 라이센스를 따릅니다.