courses
회사의 데이터베이스에서 CSV를 막 뽑아와 df.head()를 실행했더니 CUST_ID_NBR, txn_amt_usd_2, Unnamed: 7, 또는 Customer Name (Full) 같은 열이 보입니다. 뒤에 공백이 붙어 있어 KeyError가 나기 전까지는 눈치채지 못할 수도 있죠. 지저분한 열 이름은 실제 데이터 작업에서 자주 겪는 작은 마찰이며, 보통 본격적인 분석에 들어가기 전에 pandas에서 열 이름을 바꾸는 작업이 첫 단계가 됩니다.
이 튜토리얼에서는 pandas에서 열 이름을 바꾸는 방법을 다음과 같이 다룹니다.
-
.rename()로 하나 또는 여러 열 이름 바꾸기 -
df.columns또는.set_axis()로 모든 열 이름 한 번에 교체하기 -
함수를 적용해 일괄적으로 이름 변환하기
-
.str접근자로 지저분한 이름 정리하기 -
pd.read_csv()에서 로딩 시점에 열 이름 바꾸기 -
Polars에서 동일 작업 처리하기
-
KeyError와ValueError: Length mismatch피하기
이 튜토리얼은 pandas를 임포트하고 DataFrame을 만들 수 있다고 가정합니다. 고객 레코드, 매출 내보내기, 센서 읽기값 같은 현실적인 데이터셋을 사용해 실제 업무 데이터에 바로 적용할 수 있는 패턴을 보여드리겠습니다.
어떤 Pandas 열 이름 변경 방법을 선택해야 할까요?
작업 범위에 맞는 방법을 고르세요. 특정 대상만 바꾸기, 전체 교체, 모든 이름에 규칙 적용 중에서 선택합니다.
|
목표 |
방법 |
적합한 상황 |
|
특정 열 하나 또는 몇 개만 이름 변경 |
|
다른 열은 그대로 둠; 메서드 체이닝에서도 안전 |
|
모든 열 이름 교체 |
|
각 이름을 매핑하는 것보다 빠름; 체이닝이 필요하면 |
|
규칙에 따라 변경(소문자, snake_case, 공백 제거 등) |
|
모든 열을 나열하지 않고 규칙을 한 번만 표현 |
|
로딩 시점에 변경 |
|
스키마를 직접 관리하고 별도 단계 없이 처리하고 싶을 때 |
|
Polars에서 위 모든 작업 |
|
불변이고 체이닝 우선 설계이므로 |
.rename()으로 열 이름을 어떻게 바꾸나요?
.rename() 메서드는 pandas DataFrame에서 열 이름을 바꾸는 가장 유연한 방법이며, 가장 자주 사용하게 될 도구입니다.
이 메서드는 기존 이름과 새 이름을 매핑한 딕셔너리를 받고, 지정하지 않은 열은 그대로 두며, 기본적으로 원본을 수정하지 않고 새로운 DataFrame을 반환합니다. 덕분에 .rename()은 메서드 체인 내부에서도 안전하게 사용할 수 있고, 디버깅할 때도 동작을 이해하기 쉽습니다.
딕셔너리 패턴은 다음과 같습니다.
sales_data.rename(columns={"old_name": "new_name"})
딕셔너리가 낯설다면, 복습을 위해 Python 딕셔너리 메서드 튜토리얼을 살펴보시길 권합니다.
이전 copy 매개변수에 대한 참고
예시로 들어가기 전 짚고 넘어갈 점이 하나 있습니다. Pandas 3.0에서는 copy 매개변수가 폐기되었고, Copy-on-Write가 기본 동작이 되었습니다. 실무적으로는 .rename()이 데이터의 비용 큰 복사를 수행하는지 더 이상 걱정할 필요가 없다는 뜻입니다. pandas가 내부에서 지연 복사를 처리합니다. 남은 핵심 매개변수는 inplace로, 세 번째 소절에서 다루겠습니다.
단일 열 이름 바꾸기
레거시 CRM에서 내보낸 고객 레코드를 방금 로드했다고 가정해 봅시다. 열 이름이 2008년에 데이터베이스를 설계한 누군가에게는 이해됐을 약어로 되어 있어, 현재의 여러분에게는 직관적이지 않습니다. 가장 단순한 pandas 열 이름 변경 작업은 딕셔너리에서 하나의 기존 이름을 하나의 새 이름으로 매핑하는 것입니다.
import pandas as pd
customers = pd.DataFrame({
"cust_id_nbr": [4521, 4522, 4523, 4524],
"first_nm": ["Abe", "Rick", "Pat", "Kim"],
"signup_dt": ["2008-03-12", "2008-03-15", "2008-03-18", "2008-03-21"]
})
print(customers)

이제 cust_id_nbr을 더 읽기 쉬운 이름으로 바꿔봅니다.
customers_renamed = customers.rename(columns={"cust_id_nbr": "customer_id"})
print(customers_renamed)

원본 customers DataFrame은 변경되지 않았습니다. .rename()이 새로운 DataFrame을 반환했고, 이를 customers_renamed에 할당했습니다. 언급하지 않은 두 열(first_nm, signup_dt)은 그대로 유지되었습니다.
여러 열 이름 바꾸기
딕셔너리는 자연스럽게 확장됩니다. 여러 열을 바꾸려면 매핑에 키-값 쌍을 더 추가하면 됩니다.
customers_clean = customers.rename(columns={
"cust_id_nbr": "customer_id",
"first_nm": "first_name",
"signup_dt": "signup_date"
})
print(customers_clean)

또 다른 문법으로 columns 대신 mapper와 axis 인수를 사용할 수도 있습니다.
customers.rename(mapper={"cust_id_nbr": "customer_id"}, axis=1)
axis=1은 열(행 인덱스 라벨에 해당하는 axis=0이 아니라)을 대상으로 한다는 뜻입니다. 두 형태 모두 동일한 결과를 냅니다. 실무 코드에서는 한눈에 더 명확한 columns={...} 형태를 더 많이 쓰므로, 본문에서는 이 패턴을 사용하겠습니다.
유용한 디테일 한 가지: 존재하지 않는 열 이름을 키로 넘기면, .rename()은 기본적으로 조용히 무시합니다. 조금씩 다른 스키마의 DataFrame을 처리할 수 있는 재사용 함수에 편리하지만, 오타를 숨기기도 합니다. 존재하지 않는 열 이름에서 오류를 발생시키려면 errors='raise'를 전달하세요.
inplace 사용 vs. 새 DataFrame 반환
기본적으로 .rename()은 새 DataFrame을 반환하고 원본은 그대로 둡니다. 기존 DataFrame을 직접 수정하고 싶다면 inplace=True를 전달합니다.
# 새 DataFrame 반환(기본)
customers_v2 = customers.rename(columns={"first_nm": "first_name"})
# customers를 직접 수정, None 반환
customers.rename(columns={"first_nm": "first_name"}, inplace=True)
print(customers)

그렇다면 어느 쪽을 써야 할까요? 대부분의 경우 기본값인 새 DataFrame 반환이 더 낫습니다. 문제가 생겼을 때 원본 DataFrame을 그대로 확인할 수 있어 디버깅도 수월합니다. 또 과거 코드에서 SettingWithCopyWarning을 유발하던 별칭 문제를 피할 수 있습니다.
성능 때문에 inplace를 선호할 이유도 이제는 거의 없습니다. pandas 3.0+의 기본인 Copy-on-Write로 인해 비-inplace 버전은 지연 복사를 사용합니다. 실제로 뭔가 수정되기 전까지 데이터가 복제되지 않습니다. 과거의 “inplace=True가 메모리를 아낀다”는 주장은 지금은 크게 약해졌습니다.
inplace=True가 자연스러운 경우는 체이닝을 신경 쓰지 않고 단일 DataFrame을 단계별로 정리하는 짧은 탐색적 스크립트 정도입니다. 프로덕션 코드나 나중에 다시 볼 가능성이 있는 코드는 기본값을 권장합니다.
pandas에서 모든 열을 한 번에 어떻게 바꾸나요?
때로는 기존 이름을 새 이름에 매핑하고 싶지 않을 때가 있습니다. 모든 열 이름을 한 번에 교체하고 싶을 때죠. 헤더가 없는 CSV에서 pandas가 열 이름을 0, 1, 2처럼 정수로 지정했거나, 헤더 행이 다른 언어로 되어 있거나, Field1, Field2, Field3처럼 시스템이 생성한 이름일 때 자주 발생합니다.
일반적으로 두 가지 방법이 있습니다. df.columns에 직접 할당하거나 .set_axis()를 사용하는 것입니다. 결과는 같습니다. 차이는 간결함과 체이닝 가능성 사이의 트레이드오프입니다.
df.columns에 리스트 할당하기
가장 직접적인 방법은 columns 속성에 새 리스트를 할당하는 것입니다. 헤더 정보 없이 리스트의 리스트로 만든 다음 DataFrame을 보겠습니다. 헤더 없는 CSV를 읽을 때 흔히 보게 되는 형태입니다. pandas는 정수형 열 이름으로 대체합니다.
import pandas as pd
sensor_readings = pd.DataFrame([
[1.2, 22.5, 1013],
[1.5, 22.7, 1012],
[1.3, 22.6, 1013]
])
print(sensor_readings)

분석에 쓸모없는 0, 1, 2라는 열 이름을, 다음과 같이 columns 속성에 새 리스트를 할당해 바꿉니다.
sensor_readings.columns = ["wind_speed", "temperature_c", "pressure_hpa"]
print(sensor_readings)

이 방식에서 알아둘 점 두 가지.
-
리스트 길이는 정확히 일치해야 합니다. 4열 DataFrame에 3개의 이름만 넘기면 pandas는
ValueError: Length mismatch를 발생시킵니다(이 오류는 뒤에서 자세히 다룹니다). -
DataFrame을 제자리에서 수정합니다. 여기에는
inplace매개변수가 없습니다. 할당 자체가 곧 수정이기 때문입니다. 새 복사본이 필요하면 먼저.copy()를 사용하거나 아래의.set_axis()를 사용하세요.
메서드 체이닝을 위한 .set_axis() 사용
.set_axis()는 같은 일을 하지만 새 DataFrame을 반환해 다른 연산과 체이닝할 수 있습니다. 더 지저분한 데이터(불필요한 소수점, 누락값 등)가 있는 헤더 없는 DataFrame을 예로 들겠습니다.
raw_sensor = pd.DataFrame([
[1.234, 22.567, 1013],
[1.512, 22.789, 1012],
[None, 22.601, 1013],
[1.345, 22.612, 1013]
])
sensor_clean = (
raw_sensor
.set_axis(["wind_speed_mps", "temp_celsius", "pressure_hpa"], axis=1)
.round(1)
.dropna()
)
print(sensor_clean)

axis=1 인수는 열 라벨을 설정한다는 뜻입니다(axis=0은 행 인덱스). .set_axis()가 새 DataFrame을 반환하기 때문에, 실제 ETL이나 분석 코드에서 작성하는 체이닝 변환 파이프라인에 자연스럽게 들어맞습니다. 프로덕션에서 직접 할당보다 이 방법을 선호하는 주된 이유입니다.
pandas에서 함수로 열 이름을 바꾸려면?
각 기존 이름을 새 이름에 매핑하는 대신, 함수 하나를 .rename()에 전달해 모든 열 이름에 적용할 수 있습니다. 리스트가 아니라 규칙이 있을 때 적합합니다. 예를 들어 “모두 소문자” 또는 “공백을 밑줄로 바꾸기” 같은 경우입니다.
내장 문자열 함수 사용
가장 간단한 예는 대소문자 표준화입니다. str.lower, str.upper, str.title을 columns 인수에 직접 전달하세요.
import pandas as pd
orders = pd.DataFrame({
"Order ID": [1001, 1002, 1003],
"Customer Name": ["Abe", "Rick", "Pat"],
"Total Amount": [49.99, 120.00, 75.50]
})
orders_lower = orders.rename(columns=str.lower)
print(orders_lower.columns.tolist())
![]()
호출(str.lower())이 아니라 함수 자체(str.lower)를 전달한다는 점에 주의하세요. pandas가 열 이름마다 하나씩 적용합니다. 대소문자 표준화에는 깔끔한 단축키지만, 공백이나 특수문자는 처리하지 않습니다. 그런 경우에는 람다나 커스텀 함수를 사용하세요.
lambda와 커스텀 함수 사용
대소문자 변경을 넘어서는 작업에는 람다를 사용해 변환을 인라인으로 간단히 표현할 수 있습니다. 람다가 처음이라면 Python 람다 함수 입문 가이드를 참고하세요.
자주 쓰는 패턴으로, 소문자 변환과 공백을 밑줄로 바꾸기를 한 번에 처리할 수 있습니다. 앞선 예제를 사용합니다.
orders_snake = orders.rename(columns=lambda col: col.lower().replace(" ", "_"))
print(orders_snake.columns.tolist())
![]()
로직이 복잡해지면 이름이 있는 함수로 빼내세요. camelCase나 PascalCase 열 이름을 snake_case로 변환하는 헬퍼를 예로 들겠습니다.
import re
def to_snake_case(name: str) -> str:
"""Convert camelCase or PascalCase to snake_case."""
s1 = re.sub(r"(.)([A-Z][a-z]+)", r"\1_\2", name)
s2 = re.sub(r"([a-z0-9])([A-Z])", r"\1_\2", s1)
return s2.lower()
api_response = pd.DataFrame({
"userId": [1, 2, 3],
"firstName": ["Abe", "Rick", "Pat"],
"accountCreatedAt": ["2024-01-01", "2024-01-02", "2024-01-03"]
})
api_clean = api_response.rename(columns=to_snake_case)
print(api_clean.columns.tolist())
![]()
이처럼 이름이 있는 함수는 테스트, 노트북 간 재사용, 문서화가 쉬워집니다. 로직이 한 줄에 담기면 람다를, 그렇지 않으면 커스텀 함수를 쓰세요.
pandas에서 지저분한 열 이름을 일괄 정리하려면?
스프레드시트, 서드파티 API, 사람이 편집한 CSV 등에서 온 데이터는 .rename()만으로는 깔끔하게 해결하기 어려운 문제가 종종 있습니다. 예를 들면 다음과 같습니다.
- 뒤따르는 공백
- 대소문자 혼용
- 괄호
- 하이픈
- 특수문자
- 보이지 않는 유니코드 문자
이럴 때는 .str 접근자를 사용해 df.columns에 직접 연산하는 것이 가장 깔끔합니다. 이 접근자는 모든 열 이름에 대해 벡터화된 문자열 메서드(정규식 포함)를 제공합니다. 이는 탄탄한 Python 데이터 정제의 토대이기도 합니다. 열 이름을 정리하면 이후의 필터링, 머지, 시각화 등 단계에서 오류가 줄어듭니다.
공백과 특수문자 제거
여러 사람이 만진 Excel 내보내기에서 흔히 볼 법한 이름을 가진 DataFrame을 보겠습니다.
import pandas as pd
raw_export = pd.DataFrame({
" Order ID ": [1001, 1002, 1003],
"Customer Name (Full)": ["Abe", "Rick", "Pat"],
"Total Amount ($)": [49.99, 120.00, 75.50],
"Order-Date": ["2024-03-12", "2024-03-15", "2024-03-18"]
})
print(raw_export.columns.tolist())
![]()
앞뒤 공백은 가장 흔하면서도 성가신 문제입니다. 눈에 보이지 않기 때문이죠. 한 줄로 제거합니다.
raw_export.columns = raw_export.columns.str.strip()
print(raw_export.columns.tolist())
![]()
특수문자의 경우 .str.replace()가 정규식 패턴을 받습니다. 아래 패턴은 영문자, 숫자, 밑줄, 공백만 남기고 나머지를 제거합니다.
raw_export.columns = raw_export.columns.str.replace(r"[^a-zA-Z0-9_ ]", "", regex=True)
print(raw_export.columns.tolist())
![]()
하이픈, 괄호, 달러 기호가 사라졌습니다. 이제 Total Amount에는 뒤에 공백이 남았고(($)가 있던 자리), OrderDate는 하이픈이 완전히 없어졌습니다. 그래서 정리 파이프라인의 마지막에 다시 한 번 공백 제거를 하는 것입니다.
snake_case로 표준화
분석을 시작하기 전에 모든 열 이름을 snake_case로 변환하는 것이 일반적인 모범 사례입니다. 즉, 소문자, 단어는 밑줄로 구분, 특수문자 없음입니다. .str 메서드를 체인해 한 번에 달성합니다.
raw_export = pd.DataFrame({
" Order ID ": [1001, 1002, 1003],
"Customer Name (Full)": ["Abe", "Rick", "Pat"],
"Total Amount ($)": [49.99, 120.00, 75.50],
"Order-Date": ["2024-03-12", "2024-03-15", "2024-03-18"]
})
raw_export.columns = (
raw_export.columns
.str.strip() # 앞뒤 공백 제거
.str.lower() # 모두 소문자
.str.replace(r"[^a-z0-9]+", "_", regex=True) # 영숫자 외 문자를 밑줄로 치환/축약
.str.strip("_") # 앞뒤 밑줄 제거
)
print(raw_export.columns.tolist())
![]()
네 줄이면 열 이름이 예측 가능하고, 소문자이며, 밑줄로 구분됩니다. 이 패턴은 유틸리티 함수로 저장할 가치가 있습니다. 한 번 만들어 두면 들어오는 지저분한 DataFrame마다 적용하면 됩니다.
이름 변경과 열 제거를 함께 하는 경우도 많습니다. 이에 대해서는 pandas에서 열 제거 튜토리얼을 참고하세요.
pandas에서 데이터 로딩 시 열 이름을 바꾸려면?
파일을 로드하기도 전에 다른 열 이름이 필요하다는 것을 이미 알고 있다면, pd.read_csv() 내부에서 바로 이름을 바꿀 수 있습니다. names 매개변수에 이름 리스트를 전달하고 header=0을 설정해 기존 헤더 행을 건너뛰고 해당 이름을 대신 사용하도록 지정하세요.
import pandas as pd
from io import StringIO
# 데모를 위한 CSV 파일 시뮬레이션
csv_data = """txnId,custId,amt,date
1001,C01,49.99,2024-01-15
1002,C02,125.00,2024-01-16
1003,C01,79.50,2024-01-17"""
# 로딩 시점에 열 이름 변경, 원래 헤더 건너뜀
transactions = pd.read_csv(
StringIO(csv_data),
header=0,
names=["transaction_id", "customer_id", "amount_usd", "transaction_date"]
)
print(transactions)

스키마를 직접 관리하고 로딩 코드에 .rename() 같은 별도 단계를 두고 싶지 않을 때 유용한 지름길입니다. 파일에 헤더 행이 전혀 없다면 header=0은 생략하고 names=[...]만 사용해 처음부터 열 이름을 지정하세요. 로딩 옵션을 더 깊이 살펴보려면 pandas read_csv() 튜토리얼을 권합니다.
주의할 점 한 가지: 이 방식은 all-or-nothing입니다. names 매개변수는 모든 열 이름을 교체하므로, 리스트 길이가 파일의 열 개수와 정확히 일치해야 합니다. 몇 개만 바꾸고 싶다면 먼저 파일을 로드한 뒤 .rename()을 사용하세요.
이러한 패턴과 다른 일반적인 정리 작업을 함께 체험형으로 익히고 싶다면 Cleaning Data in Python 코스를 추천합니다.
Polars와 pandas에서 열 이름 바꾸기
pandas와 Polars를 함께 쓰거나 그럴 가능성이 있다면, 두 라이브러리의 열 이름 변경 방식 차이를 알아두는 것이 좋습니다. 고수준 API는 비슷하지만, 세부에서 처음에는 당황할 수 있는 차이가 있습니다. Polars는 빠른 Rust 기반 DataFrame 라이브러리로, 현대 데이터 스택에서 점점 흔해지고 있습니다. pandas에서 익힌 습관이 항상 그대로 통하진 않습니다.
핵심 아이디어는 동일합니다. 딕셔너리로 기존 이름을 새 이름에 매핑합니다. 차이는 세부에 있습니다. Polars는 설계상 불변(즉, inplace 없음)이며, 메서드 체이닝이 관용적 스타일이고, select 중 열 단위 이름 변경은 별도의 rename 단계 대신 .alias()를 사용합니다.
나란히 비교
|
작업 |
Pandas |
Polars |
|
특정 열 이름 변경 |
|
|
|
모든 열 이름 교체 |
|
|
|
select 중 이름 변경 |
먼저 선택 후 |
|
|
제자리 수정 |
|
지원 안 함. 항상 새 DataFrame 반환 |
|
관용적 스타일 |
|
항상 체이닝 |
두 라이브러리에서 동일한 이름 변경
비교를 위해 두 라이브러리에서의 간단한 이름 변경 예시를 보겠습니다.
Pandas:
# Pandas
import pandas as pd
orders_pd = pd.DataFrame({
"ord_id": [1001, 1002, 1003],
"cust_nm": ["Abe", "Rick", "Pat"]
})
orders_pd = orders_pd.rename(columns={"ord_id": "order_id", "cust_nm": "customer_name"})
print(orders_pd)

Polars:
# Polars
import polars as pl
orders_pl = pl.DataFrame({
"ord_id": [1001, 1002, 1003],
"cust_nm": ["Abe", "Rick", "Pat"]
})
orders_pl = orders_pl.rename({"ord_id": "order_id", "cust_nm": "customer_name"})
print(orders_pl)

주목할 차이 두 가지. Polars의 .rename()은 딕셔너리를 바로 받습니다. 행 인덱스 이름 바꾸기를 지원하지 않으므로 columns= 키워드가 없습니다. 그리고 결과를 다시 할당해야 합니다. Polars에는 inplace=True가 없습니다. 모든 연산이 새 DataFrame을 반환합니다.
Polars 출력은 dtype(i64, str)과 상단의 shape도 함께 보여줍니다. Polars로 옮기면 많은 분들이 좋아하는 소소한 편의성입니다.
select 중 열 이름 바꾸기
변환 중 이름을 바꿀 때는 Polars에서 .select()나 .with_columns() 내부의 .alias()를 사용합니다.
# Polars
import polars as pl
orders_pl = pl.DataFrame({
"ord_id": [1001, 1002, 1003],
"cust_nm": ["Abe", "Rick", "Pat"]
})
# 하나의 표현식에서 선택과 이름 변경
renamed = orders_pl.select(
pl.col("ord_id").alias("order_id"),
pl.col("cust_nm").alias("customer_name")
)
print(renamed)

pandas에서는 열 선택 후 .rename()을 사용하는 것이 대응 방식입니다. 어느 쪽이 더 낫다고 할 수는 없고, 각 라이브러리의 철학을 반영합니다.
두 라이브러리를 더 깊이 비교하고 싶다면 pandas vs polars 성능 튜토리얼을 추천합니다. 또한 polars를 도구 상자에 더하고 싶다면 Introduction to Polars 코스를 권합니다.
자주 발생하는 오류와 해결 방법
pandas에서 열 이름을 바꾸다 보면 두 가지 오류가 반복적으로 등장합니다. 어떤 모습인지, 왜 발생하는지, 어떻게 고치는지 살펴보겠습니다.
KeyError: 열 이름을 찾을 수 없음
기본적으로 .rename()은 존재하지 않는 키를 조용히 무시합니다. 하지만 오타를 잡아내기 위해 errors='raise'를 전달하면, 키가 없을 때 KeyError가 발생합니다.
import pandas as pd
orders = pd.DataFrame({
"order_id": [1001, 1002, 1003],
"customer_name": ["Abe", "Rick", "Pat"]
})
# 오류 발생
orders.rename(columns={"Order_ID": "order_id"}, errors="raise")
![]()
가장 흔한 원인은 대소문자 혼동(Order_ID vs order_id)이나 보이지 않는 뒤 공백("order_id " vs "order_id")입니다. KeyError가 발생하면 아래 세 가지를 순서대로 확인하세요.
- 정확한 철자와 대소문자
- 숨은 공백
- 해당 열이 앞에서 이미 이름이 바뀌었는지
실제 열 이름을 확인하려면 다음을 사용하세요.
print(orders.columns.tolist())
# 대안으로 repr() 사용
print([repr(c) for c in orders.columns])
![]()
pandas가 들고 있는 정확한 문자열을 확인하면 보통 오타가 바로 보입니다. 철자를 고치고 다시 실행하세요.
orders = orders.rename(columns={"order_id": "Order_ID"}, errors="raise")
print(orders.columns.tolist())
![]()
그렇다면 언제 errors='raise'를 쓰고, 언제 기본값인 errors='ignore'를 쓸까요?
-
기본값은 관대합니다. 스키마가 달라질 수 있는 DataFrame을 처리하는 스크립트에서, 누락된 열이 전체를 망치지 않게 할 때 유용합니다.
-
개발 중 오타를 크게 드러내고 싶을 때, 특히 조용한 실패가 이후 단계에서 몇 시간씩 디버깅을 유발하는 노트북 환경에서는
errors='raise'로 전환하세요.
ValueError: df.columns 길이 불일치
df.columns에 리스트를 할당하거나 .set_axis()를 사용할 때는 리스트 길이가 열 개수와 정확히 일치해야 합니다. 일치하지 않으면 pandas는 ValueError를 발생시킵니다.
import pandas as pd
products = pd.DataFrame({
"sku": ["A100", "A101", "A102"],
"name": ["Widget", "Gadget", "Gizmo"],
"price": [9.99, 14.99, 19.99]
})
# 오류 발생
products.columns = ["product_sku", "product_name"]
![]()
DataFrame에는 세 개의 열이 있는데, 새 이름은 두 개만 제공되었습니다. 해결책은 할당 전에 열 개수를 확인하는 것입니다.
print(len(products.columns))
products.columns = ["product_sku", "product_name", "product_price"]
print(products.columns.tolist())
![]()
열 개수가 달라질 수 있는 DataFrame을 다룰 때는 딕셔너리를 사용하는 .rename()이 더 안전합니다. 지정한 열만 건드리므로, 누락되거나 추가된 열이 있어도 코드가 깨지지 않습니다.
마무리
pandas에서 열 이름을 바꾸는 요령은 작업 범위에 맞는 방법을 고르는 데 있습니다. 어떤 방식을 택하든, 가장 큰 실용적 이득은 단일 네이밍 규칙을 정하고 모든 분석의 첫 단계로 적용하는 것입니다. Python 코드에서는 보통 snake_case를 사용합니다. 깔끔한 열 이름은 시작에 몇 초를 투자하고 프로젝트 내내 KeyError의 불쾌한 놀라움을 줄여줍니다.
표적 변경에는 딕셔너리를 사용하는 .rename()을 쓰세요. 모든 열이 새 이름이 필요하다면 df.columns에 할당하거나 .set_axis()를 사용하는 것이 모든 옛이름-새이름 매핑 딕셔너리를 만드는 것보다 빠릅니다. 공백 제거, 소문자화, camelCase 변환처럼 규칙이 있다면 함수 전달 또는 .str 접근자를 사용해 규칙을 한 번만 표현하세요. Polars도 유사한 API로 같은 작업을 수행하지만, 불변·체이닝 우선 스타일은 다른 습관을 유도합니다.
DataFrame 스킬을 계속 쌓으려면 다음 단계로 Data Manipulation with pandas 코스를 추천합니다. 체계적인 학습 경로를 원하신다면 Data Analyst in Python 커리어 트랙에서 DataFrame 조작과 함께 분석가 도구 전반을 다룹니다.
Pandas에서 열 이름 바꾸기 FAQ
pandas에서 열 이름을 어떻게 바꾸나요?
여러 방법이 있지만 가장 간단한 방법은 df = df.rename(columns={"old_name": "new_name"})를 사용하는 것입니다. DataFrame을 직접 수정하려면 inplace=True 인수를 전달하세요.
pandas에서 여러 열 이름을 어떻게 바꾸나요?
여러 열을 바꾸려면 모든 변경을 하나의 딕셔너리로 전달하세요: df.rename(columns={"old1": "new1", "old2": "new2"})
pandas DataFrame의 모든 열 이름을 어떻게 바꾸나요?
새 이름 리스트를 df.columns에 할당하세요. 주의: 리스트 길이가 열 개수와 일치해야 하며, 그렇지 않으면 ValueError가 발생합니다.
왜 df.rename()이 DataFrame을 바꾸지 않나요?
기본적으로 .rename()은 새 DataFrame을 반환합니다. 결과를 df = df.rename(...)처럼 다시 할당하거나 inplace=True를 사용하세요.
pandas에서 열 이름을 소문자로 바꾸려면?
모든 열 이름을 한 번에 소문자로 바꾸려면 df.columns = df.columns.str.lower()를 사용하세요.