본문으로 건너뛰기
김신건의 로그

[Pandas] DataFrame

· 수정 · 📖 약 1분 · 421자/단어 #python #pandas #dataframe #data-structure
Pandas DataFrame, pandas.DataFrame, 데이터프레임

정의

pandas.DataFrame 은 2차원 레이블 테이블. 각 열이 Pandas Series, 모든 열이 같은 Pandas Index (행 라벨) 를 공유. SQL 테이블 / Excel 시트 / R data.frame 의 Python 대응체.

구조 시각화

flowchart LR
    subgraph "DataFrame"
        direction LR
        IDX["Index\n(행 라벨)"]
        C1["Series: name"]
        C2["Series: age"]
        C3["Series: city"]
    end
    IDX -->|"공유"| C1
    IDX -->|"공유"| C2
    IDX -->|"공유"| C3

각 열(column)은 독립적인 Pandas Series 이고, 모든 Series 가 동일한 Index 를 공유한다. 열마다 dtype 이 달라도 된다.

생성

python
import pandas as pd

# 1. dict of lists (가장 흔함)
df = pd.DataFrame({
  'name': ['Alice', 'Bob', 'Charlie'],
  'age': [30, 25, 35],
  'city': ['Seoul', 'Busan', 'Seoul'],
})
print(df)
결과
      name  age   city
0    Alice   30  Seoul
1      Bob   25  Busan
2  Charlie   35  Seoul

다른 생성 방식

# list of dicts
pd.DataFrame([{'a': 1, 'b': 2}, {'a': 3, 'b': 4}])

# 2D array + columns
pd.DataFrame([[1, 2], [3, 4]], columns=['a', 'b'])

# from records
pd.DataFrame.from_records([(1, 'A'), (2, 'B')], columns=['id', 'name'])

# CSV 등 파일
pd.read_csv('data.csv')

# SQL 쿼리 결과 (pandas 2.x)
pd.read_sql("SELECT * FROM users", con=engine)

핵심 속성

속성의미
df.shape(n_rows, n_cols)
df.columnsIndex 객체 (열 이름)
df.indexIndex 객체 (행 라벨)
df.dtypes각 열의 타입
df.values2D numpy array
df.size원소 총 개수
df.T전치 (transpose)
df.ndim차원 수 (항상 2)
df.empty원소가 없으면 True
df.memory_usage()열별 메모리 사용량 (bytes)

빠른 탐색 메서드

df.head()         # 상위 5개
df.tail(3)
df.info()         # 메모리, dtype, null 개수
df.describe()     # 수치형 통계
df.sample(5)      # 무작위 5개
df.value_counts() # Series 만, 빈도
python
df = pd.DataFrame({
  'age': [25, 30, 35, 40, 45],
  'salary': [3000, 4500, 6000, 7500, 9000],
})
print(df.describe())
결과
             age       salary
count   5.000000     5.000000
mean   35.000000  6000.000000
std     7.905694  2371.708245
min    25.000000  3000.000000
25%    30.000000  4500.000000
50%    35.000000  6000.000000
75%    40.000000  7500.000000
max    45.000000  9000.000000

열 추가 / 수정 / 삭제

df['bmi'] = df['weight'] / (df['height']/100) ** 2   # 새 열
df['age'] = df['age'] + 1                            # 수정
df['constant'] = 100                                  # broadcast
df.drop(columns=['bmi'], inplace=False)              # 삭제 (사본 반환)

# assign 으로 method chain
df_new = (
    df
    .assign(bmi=lambda d: d['weight'] / (d['height']/100)**2)
    .assign(category=lambda d: pd.cut(d['bmi'], bins=[0, 18.5, 25, 30, 100]))
)

행 추가

# Modern pandas 2.x
new_row = pd.DataFrame([{'name': 'Dave', 'age': 28}])
df = pd.concat([df, new_row], ignore_index=True)

# (pandas 1.x 의 df.append 는 deprecated)

자주 쓰는 변환

df.rename(columns={'old': 'new'})
df.astype({'age': 'int64', 'city': 'category'})
df.set_index('name')
df.reset_index()
df.sort_values('age')
df.sort_index()

DataFrame vs Series 의 관계

df['name']           # Series
df[['name', 'age']]  # DataFrame (대괄호 2개)
df.iloc[0]           # Series (한 행)
df.iloc[[0]]         # DataFrame (한 행이지만 2D)

대괄호 개수 / iloc 단일 vs 리스트 가 반환 타입을 결정.

Copy vs View

pandas 의 가장 흔한 혼란 중 하나. 슬라이싱 결과가 원본의 뷰(view) 인지 복사본(copy) 인지 불명확하다.

flowchart TD
    DF["원본 DataFrame"] --> SLICE["df[mask] / df[cols]"]
    SLICE -->|"view 일 때"| V["수정 시 원본도 변경"]
    SLICE -->|"copy 일 때"| C["수정해도 원본 불변"]
    V --> WARN["SettingWithCopyWarning"]
# pandas 2.0 CoW (Copy-on-Write) 이전
sub = df[df['age'] > 30]          # view 일 수도, copy 일 수도
sub['new'] = 1                     # ⚠️ SettingWithCopyWarning

# 올바른 방법: 명시적 .copy()
sub = df[df['age'] > 30].copy()
sub['new'] = 1                     # 원본 안전

# pandas 2.0+ CoW: 항상 copy 처럼 동작 (view 수정 불가)

WARNING

pandas 2.0 부터 Copy-on-Write (CoW) 가 기본 도입됐다. df[...] 로 선택한 결과에 대입하면 ChainedAssignmentError. 조건부 수정은 반드시 .loc[행, 열] = 한 번에.

성능 팁

# dtype 을 명시해 메모리 절약
df = pd.DataFrame({
    'age': pd.array([25, 30, 35], dtype='int8'),     # int64 대신 1/8 메모리
    'city': pd.Categorical(['Seoul', 'Busan', 'Seoul']),  # category 타입
})

# 컬럼 많을 때 필요한 것만 read_csv
df = pd.read_csv('data.csv', usecols=['name', 'age'])

# inplace 는 메모리 절약 아님 (사본 생성 후 교체)
df.sort_values('age', inplace=True)   # 권장 안 함
df = df.sort_values('age')            # 더 명확

자세히는 Pandas 성능 / 메모리 최적화.

함정

1. SettingWithCopyWarning

sub = df[df['age'] > 20]
sub['new'] = 1      # ⚠️ view 인지 copy 인지 모름

# 해법: .loc 한 번에 처리
df.loc[df['age'] > 20, 'new'] = 1    # ✓

2. inplace 의 오해

df.drop(columns=['a'], inplace=True)
# inplace 는 내부적으로 복사 후 교체, 메모리 절약 없음
# 그리고 method chain 불가, 디버깅 어려움
# 반환값 None 이라 실수 유발

CAUTION

inplace=True 는 실질적 이점이 없다. 반환값이 None 이라 df = df.sort_values(...) 처럼 쓰려다 데이터를 잃을 수 있다.

3. dtypes 혼용

df = pd.DataFrame({'a': [1, 2, None]})
df.dtypes    # float64 (int + None → float)

# pandas 2.0 nullable int
df = pd.DataFrame({'a': pd.array([1, 2, None], dtype='Int64')})
df.dtypes    # Int64 (nullable)

4. 빈 DataFrame 생성 후 루프 append

# ❌ 매우 느림
results = pd.DataFrame()
for row in data:
    results = pd.concat([results, pd.DataFrame([row])])

# ✓ 리스트에 모아 한 번에
rows = []
for row in data:
    rows.append(row)
df = pd.DataFrame(rows)

관련 위키

이 글의 용어 (9개)
[Pandas] .loc / .ilocpandas
정의 - : 라벨 기반 인덱싱 (index/column 이름) - : 정수 위치 기반 인덱싱 (0-based) 이 두 indexer 가 pandas 선택의 표준. 만으로는 헷갈리…
[Pandas] 개요pandas
정의 pandas 는 Python 의 데이터 분석/조작 라이브러리. 두 가지 핵심 자료형을 중심으로 동작한다. - : 1차원 레이블 배열 (NumPy array + index) …
[Pandas] 성능 / 메모리 최적화pandas
정의 pandas 의 흔한 성능 함정과 최적화 패턴. 벡터화 + dtype 선택 + 알고리즘 의 조합이 핵심. 사용 상황 | 상황 | 권장 접근 | |:---|:---| | 단순…
[Pandas] 컬럼 선택pandas
정의 DataFrame 에서 하나 또는 여러 컬럼을 선택 하는 방법들. 가장 기본이자 가장 자주 쓰는 동작. 선택 방법 분류 4 가지 기본 방식 단일 vs 다중 (반환 타입 차이…
[Pandas] Boolean Indexingpandas
정의 Boolean Indexing 은 True/False 의 Series 를 인덱서로 전달 해 행을 선택하는 패턴. pandas 의 가장 흔한 필터링 방법. 마스크 생성과 적용…
[Pandas] Indexpandas
정의 는 행 / 열 라벨을 보관하는 객체. / 의 모든 라벨은 Index. 정렬, 정합성, 빠른 lookup 의 기반. 기본은 RangeIndex (0, 1, 2, ...) 지만…
[Pandas] read_csv / to_csvpandas
정의 는 CSV(Comma-Separated Values) 또는 구분자 기반 텍스트 파일을 DataFrame 으로 읽는 함수. pandas 사용의 출발점. 반대 방향은 : Dat…
[Pandas] Seriespandas
정의 는 1차원 레이블 배열. NumPy + 의 결합. 의 한 열이 곧 Series. dict-like (key = index label) 이자 list-like (순서 있는 배…
[Pandas] SettingWithCopyWarningpandas
정의 은 pandas 가 가장 자주 던지는 경고. chained indexing 으로 view 인지 copy 인지 모호한 상태에 값을 할당 할 때 발생. 사용 상황 다음 상황에서…

💬 댓글

사이트 검색 / 명령어

검색

스크롤 = 확대/축소 · 드래그 = 이동 · 0 = 원래 크기 · ESC = 닫기