Pandas & NumPy Academy · 강의

인덱스 정렬과 재인덱싱

reindex()로 두 DataFrame을 공통 인덱스에 맞추고 누락된 레이블을 채우며 산술 연산에서 인덱스가 정렬되는 방식을 이해합니다.

레슨 3/413개 단계

인덱스 정렬과 재인덱싱은(는) CoddyKit의 무료 Pandas & NumPy Academy 강의입니다. 이것은 4개 중 3번째 강의입니다. 아래에서 전체 강의를 무료로 읽을 수 있으며, 내장 코드 에디터와 24/7 AI 튜터와 함께 브라우저에서 직접 실습할 수 있습니다. 이 강의는 Pandas & NumPy Academy 학습 경로의 일부이며, 진행 상황이 웹과 CoddyKit 앱에 동기화됩니다. Pandas & NumPy Academy 강의에는 총 4개의 강의가 포함되어 있습니다.

Pandas가 인덱스를 정렬하는 방법

Pandas의 가장 강력하면서도 때로는 예상하기 어려운 동작 중 하나는 자동 인덱스 정렬입니다. 두 Series 또는 DataFrame을 더하거나 빼거나 그 밖의 방식으로 결합하면 Pandas는 먼저 인덱스 레이블을 기준으로 정렬한 후 연산을 수행합니다. 일치하는 레이블끼리 연산되고, 일치하지 않는 레이블에서는 NaN이 생성됩니다. 덕분에 정렬되지 않은 데이터로 인한 오류가 조용히 발생하는 것을 막고, 먼저 수동으로 정렬하거나 순서를 재배치하지 않아도 서로 다른 출처의 데이터를 안전하게 결합할 수 있습니다.

import pandas as pd

s1 = pd.Series([10, 20, 30], index=['a', 'b', 'c'])
s2 = pd.Series([1, 2, 3], index=['b', 'c', 'd'])

# Alignment in action: a→NaN, d→NaN
result = s1 + s2
print('s1 + s2 with automatic alignment:')
print(result)

정렬되지 않은 인덱스에서 발생하는 NaN

인덱스 레이블이 일치하지 않으면 Pandas는 누락된 항목을 NaN으로 채웁니다. 이는 의도된 동작으로, '두 피연산자 중 하나에서 대응하는 값을 찾지 못했다'는 의미입니다. 두 Series 또는 DataFrame 사이의 산술 연산 결과에 예상하지 못한 NaN 값이 있는지 항상 확인하세요. NaN은 인덱스가 정렬되지 않았다는 신호일 수 있습니다. 산술 메서드에서 fill_value=0을 사용하면 누락된 정렬 값을 NaN이 전파되도록 두는 대신 0으로 처리할 수 있습니다(s1.add(s2, fill_value=0)).

import pandas as pd

s1 = pd.Series({'a': 10, 'b': 20, 'c': 30})
s2 = pd.Series({'b': 1, 'c': 2, 'd': 3})

# Default: NaN where labels don't match
print('Default (NaN for unmatched):')
print(s1 + s2)

# fill_value=0: treat missing as zero
print('\nWith fill_value=0:')
print(s1.add(s2, fill_value=0))

DataFrame 산술 연산의 정렬

두 DataFrame을 결합할 때 정렬은 행과 열 모두에 적용됩니다. 결과에는 두 인덱스 집합과 두 열 집합의 합집합이 포함되며, 어느 한 DataFrame에도 값이 없는 위치에는 NaN이 들어갑니다. 이는 인덱스와 열에 동시에 적용하는 완전 외부 조인과 같습니다. 따라서 서로 다른 회계 기간의 DataFrame도 안전하게 더할 수 있습니다. 한쪽에만 존재하는 월에는 NaN이 들어가며, 이후 이를 채우거나 삭제할 수 있습니다.

import pandas as pd

df1 = pd.DataFrame({'revenue': [100, 200], 'cost': [80, 150]}, index=['Jan', 'Feb'])
df2 = pd.DataFrame({'revenue': [120, 210], 'headcount': [5, 6]}, index=['Feb', 'Mar'])

result = df1 + df2
print('Combined DataFrame (union of index and columns):')
print(result)

reindex() 메서드

df.reindex(new_index)는 new_index 레이블 목록에 맞춰진 새 DataFrame을 반환합니다. 원래 인덱스와 새 인덱스 모두에 존재하는 레이블은 유지되고, 원래 인덱스에는 없지만 new_index에 있는 레이블에는 NaN이 들어가며, 원래 인덱스에는 있지만 new_index에는 없는 레이블은 삭제됩니다. 이는 연산을 수행하기 전에 DataFrame을 대상 레이블 집합에 맞추는 명시적인 방법입니다.

import pandas as pd

s = pd.Series({'a': 10, 'b': 20, 'c': 30})

# Reindex to a new label set
reindexed = s.reindex(['b', 'c', 'd', 'e'])
print('Original:', s.index.tolist())
print('New index: [b, c, d, e]')
print('\nReindexed Series:')
print(reindexed)
# b, c preserved; d, e → NaN; a dropped

재인덱싱 후 누락된 값 채우기

reindex()는 새 레이블에 사용할 상수를 지정하는 fill_value 매개변수와 앞방향 채우기('ffill') 또는 뒷방향 채우기('bfill')를 지정하는 method 매개변수를 지원합니다. 이러한 채우기 메서드는 완전한 날짜 범위에 맞춰 Series를 재인덱싱하고, 누락된 날짜를 NaN 대신 마지막으로 알려진 값으로 채우려는 시계열 데이터에서 특히 유용합니다.

import pandas as pd

# Sparse daily data with gaps
s = pd.Series(
    [10, 20, 30],
    index=pd.to_datetime(['2024-01-01', '2024-01-03', '2024-01-07'])
)

# Reindex to complete date range
full_range = pd.date_range('2024-01-01', '2024-01-07')
print('Forward fill (carry last known value):')
print(s.reindex(full_range, method='ffill'))

print('\nFill with 0:')
print(s.reindex(full_range, fill_value=0))

열 재인덱싱

reindex는 열에도 사용할 수 있습니다: df.reindex(columns=['col1', 'col2', 'new_col']). 원래 DataFrame에 없는 새 열은 NaN으로 추가됩니다. 새 목록에 없는 기존 열은 삭제됩니다. 이는 서로 다른 출처에서 가져와 열 집합이 일관되지 않을 수 있는 여러 DataFrame에 표준 열 스키마를 적용할 때 유용합니다.

import pandas as pd

df = pd.DataFrame({
    'name': ['Alice', 'Bob'],
    'age': [30, 25],
    'city': ['NY', 'LA']
})

# Enforce a canonical column order and add missing columns
canonical_cols = ['name', 'age', 'email', 'city', 'country']
df_reindexed = df.reindex(columns=canonical_cols)
print(df_reindexed)
# 'email' and 'country' are new → NaN

align()으로 두 객체 동기화하기

s1.align(s2)는 동일한 인덱스를 가진 두 개의 새 객체를 반환하므로 요소별 연산을 수행할 수 있습니다(join 매개변수에 따라 합집합 또는 교집합 사용). 이는 두 객체를 동시에 같은 레이블 집합으로 재인덱싱하는 것과 같습니다. 공통 레이블만 유지하려면 join='inner'를 사용하고, 불일치하는 위치에 NaN을 넣으면서 두 객체의 모든 레이블을 유지하려면 기본값인 join='outer'를 사용합니다.

import pandas as pd

s1 = pd.Series({'a': 10, 'b': 20, 'c': 30})
s2 = pd.Series({'b': 1, 'c': 2, 'd': 3})

# Align to common labels only (inner join)
s1_aligned, s2_aligned = s1.align(s2, join='inner')
print('Inner-aligned s1:')
print(s1_aligned)
print('Inner-aligned s2:')
print(s2_aligned)

print('\nProduct on common labels:')
print(s1_aligned * s2_aligned)

merge와 산술 연산의 정렬 비교

Pandas는 DataFrame을 결합하는 두 가지 방식을 제공합니다. 하나는 merge/join(SQL 방식의 명시적인 키 일치)이고, 다른 하나는 인덱스 정렬을 사용하는 산술 연산(암시적인 레이블 기반 방식)입니다. 명시적인 키 열이 있는 구조화된 표를 결합할 때는 merge를 사용합니다. 자연스럽게 동일한 인덱스를 공유해야 하는 DataFrame 사이에서 계산할 때는 산술 정렬을 사용합니다. 예를 들어 둘 다 (region, month)로 인덱싱된 비용 DataFrame을 매출 DataFrame에서 빼는 경우입니다.

import pandas as pd

# Two DataFrames sharing the same index
revenue = pd.Series({'North': 500, 'South': 300, 'East': 450})
costs = pd.Series({'North': 350, 'South': 280, 'West': 400})

# Automatic alignment: 'East' and 'West' don't match → NaN
profit = revenue - costs
print('Profit by region:')
print(profit)

# If you want only common regions
profit_inner = revenue.align(costs, join='inner')[0] - revenue.align(costs, join='inner')[1]
print('\nProfit (common regions only):')
print(profit_inner)

연산 전에 인덱스가 같은지 확인하기

두 DataFrame에 연산을 수행하기 전에 (df1.index == df2.index).all()로 인덱스가 일치하는지 확인합니다. 인덱스의 순서만 다르다면 비교하기 전에 둘 다 정렬합니다. 서로 다른 출처에서 불러온 DataFrame은 산술 연산 전에 명시적으로 정렬하거나 재인덱싱하는 것이 좋습니다. 그러면 실수로 NaN이 전파되는 것을 방지할 수 있습니다. 정렬에 대한 가정은 주석이나 파이프라인 로그에 기록합니다.

import pandas as pd

df1 = pd.DataFrame({'sales': [100, 200, 300]}, index=['Q1', 'Q2', 'Q3'])
df2 = pd.DataFrame({'cost': [80, 160, 240]}, index=['Q1', 'Q2', 'Q3'])

# Check index equality
if (df1.index == df2.index).all():
    print('Indices match — safe to combine.')
    combined = pd.concat([df1, df2], axis=1)
    combined['profit'] = combined['sales'] - combined['cost']
    print(combined)
else:
    print('Indices differ — align before combining!')

실전 패턴: 형태 표준화

여러 파일이나 API 호출에서 데이터를 불러올 때 각 배치가 서로 다른 키의 하위 집합을 포함하는 경우가 많습니다. 연결하거나 집계하기 전에 모든 배치를 fill_value=0과 함께 알려진 전체 키 공간으로 재인덱싱합니다. 이렇게 하면 연산 전에 모든 배치가 동일한 형태(동일한 인덱스와 동일한 열)를 갖게 되어, 집계 결과를 잘못 만들 수 있는 형태 불일치를 조용히 지나치는 일을 방지할 수 있습니다.

import pandas as pd

# Two sales batches with different product sets
batch1 = pd.Series({'laptop': 50, 'phone': 80, 'tablet': 30})
batch2 = pd.Series({'phone': 90, 'tablet': 40, 'headphones': 60})

# Full product catalogue
all_products = ['laptop', 'phone', 'tablet', 'headphones']

# Standardise both to the full catalogue
b1 = batch1.reindex(all_products, fill_value=0)
b2 = batch2.reindex(all_products, fill_value=0)

total = b1 + b2
print('Total sales per product:')
print(total)

인덱스 정렬의 특수 사례

중요한 특수 사례는 다음과 같습니다. 중복 레이블 — 두 Series에 모두 중복된 인덱스 레이블이 있으면 정렬 과정에서 카테시안 곱과 유사하게 확장되어 NaN 값이 많이 생성됩니다(판다스는 어떤 중복 항목끼리 대응하는지 추정하지 않습니다). 산술 정렬을 수행하기 전에 항상 인덱스가 고유한지 확인하십시오. 정수 인덱스와 객체 인덱스 — RangeIndex(0,5)와 Int64Index([0,1,2,3,4])는 하나가 추론된 인덱스이고 다른 하나가 명시적인 인덱스이므로 연산 후 완벽하게 정렬되지 않을 수 있습니다. reset_index(drop=True)를 사용하여 표준화하십시오.

import pandas as pd

# Duplicate label alignment — produces unexpected expansion
s1 = pd.Series([1, 2, 3], index=['a', 'a', 'b'])
s2 = pd.Series([10, 20], index=['a', 'b'])

result = s1 + s2
print('Result with duplicate indices (unexpected expansion):')
print(result)
print('\nAlways ensure unique indices before arithmetic!')

빠른 확인

이 레슨에서 배운 인덱스 정렬과 재인덱싱에 대한 이해도를 확인해 보십시오.

레슨 요약

이 레슨에서는 다음을 배웠습니다. 판다스는 산술 연산에서 자동 인덱스 정렬을 수행하며, 일치하지 않는 레이블에는 NaN을 생성합니다. reindex()는 결측 레이블에 대한 채우기 옵션과 함께 DataFrame을 대상 레이블 집합에 맞춥니다. 또한 align()은 두 객체를 동시에 동일한 인덱스에 맞춥니다. 다음에는 정렬된 인덱스의 성능상 이점과 이를 timeit으로 측정하는 방법을 살펴보겠습니다.

무료로 시작

AI 튜터와 함께 Python을(를) 배우세요 — 무료

브라우저에서 실제 코드를 작성하고 실행하며, 24/7 AI 튜터로부터 즉각적인 도움을 받고, 웹이나 앱에서 중단한 부분부터 계속 학습하세요.

코스
30
레슨
120

자주 묻는 질문

“인덱스 정렬과 재인덱싱” 강의는 무료인가요?

네 — “인덱스 정렬과 재인덱싱” 전체 내용을 이 웹사이트에서 무료로 읽을 수 있습니다. 인터랙티브하게 실습하려면(내장 코드 에디터와 24/7 AI 튜터), CoddyKit PRO로 업그레이드하면 Pandas & NumPy Academy 강의 전체를 잠금 해제할 수 있습니다. Pandas & NumPy Academy 강의에는 총 4개의 강의가 포함되어 있습니다.

“인덱스 정렬과 재인덱싱”에서 뭘 배우나요?

reindex()로 두 DataFrame을 공통 인덱스에 맞추고 누락된 레이블을 채우며 산술 연산에서 인덱스가 정렬되는 방식을 이해합니다. 브라우저에서 직접 실행하는 실습 코드로 Pandas & NumPy Academy을(를) 배우며, 24/7 AI 튜터가 강의를 진행하면서 질문에 답변해줍니다.

Pandas & NumPy Academy을(를) 시작하는 데 경험이 필요한가요?

사전 경험은 필요하지 않습니다. CoddyKit의 Pandas & NumPy Academy은(는) 초급자부터 고급 학습자까지를 위해 구성되어 있으므로, 여기서 시작하거나 처음부터 시작할 수 있으며 자신의 속도대로 진행할 수 있습니다. 이것은 4개 중 3번째 강의입니다.

“인덱스 정렬과 재인덱싱” 강의는 얼마나 걸리나요?

대부분의 CoddyKit 강의는 약 5~10분이 소요됩니다. 각 강의는 간결하고 인터랙티브하여 꾸준한 진행이 가능하며, 웹과 앱에서 중단한 부분부터 바로 시작할 수 있습니다.

이 Pandas & NumPy Academy 강의에서 코드를 작성하고 실행할 수 있나요?

네. 모든 Pandas & NumPy Academy 강의에는 내장 코드 에디터가 포함되어 있으므로, 브라우저에서 바로 실제 코드를 작성하고 실행한 후 즉시 AI 피드백을 받을 수 있습니다 — 로컬 설정이 필요 없습니다.

이 강의의 모든 강의

  1. MultiIndex 만들기
  2. MultiIndex에서 데이터 선택하기
  3. 인덱스 정렬과 재인덱싱
  4. 정렬된 인덱스의 성능 이점
← Pandas & NumPy Academy(으)로 돌아가기