인덱스,시리즈,데이터프레임
| topics | 100-데이터분석 & AI 103 데이터 분석,처리 |
| types | 학습 레퍼런스 |
| tags | |
| references |
인덱스, 시리즈, 데이터프레임
기본 개념 정리
| 구분 | 설명 | 구조 | 예시 |
|---|---|---|---|
| 인덱스(Index) | 행(또는 열)을 식별하는 라벨(label) | 1차원 라벨 | [0, 1, 2] 또는 ['a', 'b', 'c'] |
| 시리즈(Series) | 1차원 데이터 구조 (값 + 인덱스) | 1차원 | 0: 10, 1: 20, 2: 30 |
| 데이터프레임(DataFrame) | 2차원 데이터 구조 (시리즈 여러 개) | 2차원(표) | 행과 열이 있는 엑셀 같은 테이블 |
인덱스 (Index)
데이터의 각 행(또는 열)을 식별하는 역할을 하는 라벨이다.
특징
- 시리즈와 데이터프레임 모두 인덱스를 가진다
- 정수, 문자열, 날짜 등 다양한 형태 가능
- 데이터를 담지 않고, 식별·정렬·슬라이싱에 사용
예시
import pandas as pd
# <span id="인덱스-예시"></span>인덱스 예시
idx = pd.Index([0, 1, 2]) # 정수 인덱스
idx = pd.Index(['a', 'b', 'c']) # 문자열 인덱스
idx = pd.DatetimeIndex(['2024-01-01', '2024-01-02']) # 날짜 인덱스
시리즈 (Series)
1차원 데이터 구조로, 값과 인덱스로 구성된다.
왜 리스트 대신 시리즈를 쓸까?
리스트
- 값만 저장
- 순서로만 접근 (
list[0])
시리즈
- 값 + 라벨(인덱스) 저장
- 라벨로 접근 가능 (
series['a']) - 벡터 연산 지원
딕셔너리처럼 key-value 구조로도 볼 수 있지만, 순서가 있고 벡터 연산이 가능하다는 게 다르다.
시리즈 생성
# <span id="리스트로-생성"></span>리스트로 생성
s = pd.Series([10, 20, 30])
print(s)
# <span id="0-10"></span>0 10
# <span id="1-20"></span>1 20
# <span id="2-30"></span>2 30
# <span id="인덱스-지정"></span>인덱스 지정
s = pd.Series([10, 20, 30], index=['a', 'b', 'c'])
print(s)
# <span id="a-10"></span>a 10
# <span id="b-20"></span>b 20
# <span id="c-30"></span>c 30
# <span id="딕셔너리로-생성"></span>딕셔너리로 생성
s = pd.Series({'a': 10, 'b': 20, 'c': 30})
시리즈 → 데이터프레임 변환
s = pd.Series(
['4 cups', '1 cup', '2 large', '1 can'],
index=['Flour', 'Milk', 'Eggs', 'Spam'],
name='Dinner' # 이게 컬럼명이 됨
)
df = s.to_frame()
print(df)
# <span id="dinner"></span>Dinner
# <span id="flour-4-cups"></span>Flour 4 cups
# <span id="milk-1-cup"></span>Milk 1 cup
# <span id="eggs-2-large"></span>Eggs 2 large
# <span id="spam-1-can"></span>Spam 1 can
name 파라미터: 시리즈에 이름을 주면, 데이터프레임으로 변환할 때 컬럼명이 된다.
데이터프레임 (DataFrame)
2차원 데이터 구조로, 여러 개의 시리즈(열)가 모여서 만들어진다.
왜 필요한가?
엑셀 스프레드시트나 SQL 테이블 같은 구조
- 행과 열 모두 인덱스(라벨)를 가진다
- 각 열은 서로 다른 데이터 타입 가능
- 데이터 분석의 기본 단위
데이터프레임 생성
# <span id="딕셔너리로-생성"></span>딕셔너리로 생성
df = pd.DataFrame({
'Apples': [30, 41],
'Bananas': [21, 34]
})
print(df)
# <span id="apples-bananas"></span>Apples Bananas
# <span id="0-30-21"></span>0 30 21
# <span id="1-41-34"></span>1 41 34
# <span id="인덱스-지정"></span>인덱스 지정
df.index = ['2017 Sales', '2018 Sales']
print(df)
# <span id="apples-bananas"></span>Apples Bananas
# <span id="2017-sales-30-21"></span>2017 Sales 30 21
# <span id="2018-sales-41-34"></span>2018 Sales 41 34
행 추가
# <span id="새로운-행-추가"></span>새로운 행 추가
new_row = pd.DataFrame(<a href="/pages/45%2C-38.html" class="wiki-link">45, 38</a>, columns=['Apples', 'Bananas'])
df = pd.concat([df, new_row], ignore_index=True)
데이터 접근
# <span id="컬럼-접근-시리즈-반환"></span>컬럼 접근 (시리즈 반환)
df['Apples']
# <span id="특정-값-접근-권장-방법-loc-사용"></span>특정 값 접근 (권장 방법: loc 사용)
df.loc['2017 Sales', 'Apples'] = 35
# <span id="이렇게도-되긴-하지만-loc를-권장"></span>이렇게도 되긴 하지만 loc를 권장
# <span id="dfapples2017-sales-35-settingwithcopywarning-발생-가능"></span>df['Apples']['2017 Sales'] = 35 # SettingWithCopyWarning 발생 가능
왜 loc를 써야 할까?
df['col']['row']방식은 체이닝이라 경고가 뜬다.loc는 명확하게 한번에 접근하므로 안전하다.
정리
차이점 요약
- 인덱스: 데이터의 위치를 식별하는 라벨 (1차원)
- 시리즈: 값 + 인덱스로 구성된 1차원 데이터 (컬럼 1개)
- 데이터프레임: 여러 시리즈(컬럼)를 모은 2차원 데이터 (행과 열, 각자 인덱스)
관계
데이터프레임 = 여러 개의 시리즈
시리즈 = 1개의 컬럼 + 인덱스
데이터프레임에서 하나의 컬럼을 선택 → 시리즈 반환
핵심: 데이터프레임에서 하나의 열을 선택하면 시리즈가 된다. 시리즈와 데이터프레임 모두 인덱스를 가진다는 게 공통점이다.