rename 함수
함수 이름 | pandas.DataFrame.rename() |
역할 | 데이터프레임의 행(인덱스) 또는 열(컬럼)의 이름을 변경 |
왜 사용? | 데이터 정리를 위해 컬럼명을 직관적으로 변경하거나, 불필요한 특수문자를 제거할 때 사용 |
어떻게 동작? | columns 또는 index 매개변수를 사용하여 딕셔너리 형태로 변경할 이름을 지정 |
기본 문법 | df.rename(columns={'old_name': 'new_name'}, index={0: 'first_row'}, inplace=False) |
inplace 옵션 | True로 설정하면 원본 데이터프레임을 직접 변경, False면 변경된 복사본을 반환 |
주의할 점 | 딕셔너리에 없는 컬럼이나 인덱스는 변경되지 않음 |
astype 함수
함수 이름 | pandas.DataFrame.astype() |
역할 | 데이터프레임의 특정 열(컬럼) 또는 전체 데이터의 자료형을 변환 |
왜 사용? | 연산을 위해 정수↔문자 변환, 메모리 최적화, 데이터 정제 등의 목적 |
어떻게 동작? | astype() 함수에 변환할 자료형을 딕셔너리 형태 또는 단일 타입으로 전달 |
기본 문법 | df.astype({'컬럼명': 타입}) 또는 df['컬럼명'].astype(타입) |
inplace 옵션 | 없음. 원본을 유지하고 변환된 새로운 데이터프레임 반환 |
주의할 점 | 변환 불가능한 데이터가 있을 경우 오류 발생 (errors='ignore' 또는 'coerce' 옵션 사용 가능) |
📝 errors 옵션 비교 표
옵션의미 (영어 해석)설명동작 방식예제 결과 (문자 → 숫자 변환 시)
errors='raise' (기본값) | raise = 오류를 발생시키다 | 변환할 수 없는 값이 있으면 즉시 오류 발생 | 변환 실패 시 ValueError 발생 | '123' → 123, 'abc' → ❌ 오류 발생 |
errors='ignore' | ignore = 무시하다 | 변환할 수 없는 값이 있으면 무시하고 원래 값 유지 | 변환 가능하면 변환, 불가능하면 기존 값 유지 | '123' → 123, 'abc' → 'abc' |
errors='coerce' | coerce = 강제로 바꾸다 | 변환할 수 없는 값은 NaN(결측치)로 대체 | 변환 가능하면 변환, 불가능하면 NaN으로 변환 | '123' → 123, 'abc' → NaN |
✅ 'raise'는 변환 불가능하면 오류 발생
✅ 'ignore'는 변환 불가능하면 기존 값 유지
✅ 'coerce'는 변환 불가능하면 NaN으로 변환
📌 copy=True가 원래 어떻게 동작해야 할까?
- copy=True는 새로운 데이터프레임을 만들어 반환하므로, 원본 df는 영향을 받지 않아야 합니다.
- 하지만 df_copy['A'][0] = 100 같은 코드가 실행되면, 내부적으로 원본이 수정될 수도 있습니다.
- Pandas에서는 .loc[]을 사용하지 않으면, **"원본을 수정할 수도 있고 아닐 수도 있는 애매한 상황"**이 발생할 수 있어요.
🧐 .loc[]을 사용하지 않으면 왜 애매한 상황이 발생할까?
Pandas에서는 기본적인 슬라이싱(df['A'][0] = 값)을 사용하면, 원본이 변경될 수도 있고 안 될 수도 있는 애매한 상황이 발생할 수 있어요.
이것은 "뷰(View)와 복사본(Copy)" 문제 때문인데, Pandas는 상황에 따라 데이터의 참조(View)를 반환할 수도 있고, 새로운 복사본(Copy)을 반환할 수도 있기 때문입니다.
1️⃣ Pandas는 언제 View를 반환하고 언제 Copy를 반환할까?
Pandas에서 데이터프레임을 조작할 때, 두 가지 방식이 존재합니다.
- ✅ View(참조) 반환: 원본 데이터와 메모리를 공유 → 값을 변경하면 원본도 같이 변경될 수 있음
- ✅ Copy(복사본) 반환: 원본과 독립적인 새로운 데이터 생성 → 값을 변경해도 원본에는 영향 없음
그러나 Pandas는 특정한 경우에 자동으로 View를 줄지, Copy를 줄지 결정하는데,
이 규칙이 완전히 명확하지 않아서 개발자가 예상하지 못한 동작이 나올 수 있어요.
2️⃣ 예제 1: 슬라이싱 시 View가 반환될 수도 있고 Copy가 반환될 수도 있는 경우
import pandas as pd
df = pd.DataFrame({'A': [1, 2, 3, 4, 5]})
df_subset = df[:3] # 원본의 일부를 슬라이싱
df_subset['A'][0] = 100 # 첫 번째 값 변경 시 원본에도 영향을 줄까?
print(df)
🔹 결과가 항상 일정하지 않을 수 있음!
- 어떤 경우에는 df_subset이 **원본 df의 View(참조)**라서 df_subset['A'][0]을 바꾸면 원본도 변함
- 어떤 경우에는 df_subset이 **새로운 복사본(Copy)**이라서 원본이 변하지 않음
이런 애매한 동작이 있기 때문에, Pandas에서는 아래와 같은 경고를 띄웁니다.
SettingWithCopyWarning:
A value is trying to be set on a copy of a slice from a DataFrame
즉, 슬라이싱된 데이터가 원본의 View인지 Copy인지 확실하지 않으므로, 변경하면 안 된다는 경고입니다.
3️⃣ .loc[]를 사용하면 항상 Copy or View를 명확하게 지정할 수 있음
위와 같은 애매한 동작을 피하려면 .loc[]를 사용하여 직접 값을 변경해야 합니다.
import pandas as pd
df = pd.DataFrame({'A': [1, 2, 3, 4, 5]})
df_subset = df[:3] # 원본의 일부를 슬라이싱
df_subset.loc[0, 'A'] = 100 # 확실하게 원본 데이터의 값을 변경
print(df)
✅ .loc[]를 사용하면 원본 데이터가 명확하게 수정됨!
✅ df_subset.loc[0, 'A'] = 100을 하면, df_subset이 View인지 Copy인지 관계없이 확실하게 df[0, 'A'] 값이 바뀝니다.
🚀 결론
✔ .loc[] 없이 df['A'][0] = 값 같은 방식으로 데이터를 수정하면, 원본이 바뀔 수도 있고 안 바뀔 수도 있음
✔ Pandas의 "View vs Copy" 동작 방식이 항상 일관되지 않기 때문에, .loc[]을 사용하여 명확하게 데이터 변경을 지정하는 것이 안전
✔ Pandas가 "SettingWithCopyWarning"을 띄우는 이유도 바로 이 문제 때문
그래서 Pandas에서는 .loc[]을 사용하여 원본을 직접 수정하는 것이 가장 안전한 방법입니다!
표로 정리
✅ .loc[] 사용 | 명확하게 원본을 직접 수정 | df.loc[0, 'A'] = 100 | 항상 원본이 변경됨 | 안전하고 예측 가능 |
⚠ 슬라이싱 후 수정 (df['A'][0] = 값) | 원본이 변경될 수도 있고, 아닐 수도 있음 (View or Copy 문제) | df_subset = df[:3] df_subset['A'][0] = 100 |
Pandas 내부 동작에 따라 다름 | SettingWithCopyWarning 발생 가능 |
⚠ copy=False 사용 (astype 예제) | 원본을 직접 수정하려 하지만, 내부적으로 복사될 수도 있음 | df_new = df.astype(int, copy=False) | 상황에 따라 다름 | 원본이 변할 수도 있고 아닐 수도 있음 |
✅ copy=True 사용 (astype 예제) | 원본을 유지하고 새로운 복사본을 반환 | df_new = df.astype(int, copy=True) | 항상 원본 유지됨 | 원본을 안전하게 보호 |
'ChatGPT 아카이브 > Pandas' 카테고리의 다른 글
pivot vs pivot_table 차이점 (0) | 2025.03.05 |
---|---|
concate / 축(axis) 번호 살펴보기 (0) | 2025.03.05 |
dropna() vs fillna() 비교 / NaN과 None의 차이 (0) | 2025.03.04 |
drop_duplicates() 함수 파헤치기 (0) | 2025.03.04 |
표현식(expression)과 할당문(statement) 둘 다 함수 return 값에 올 수 있을까? + 할당표현식( := ) (0) | 2025.03.04 |