안녕하세요! 이번 글에서는 Pandas를 사용하다가 마주친 SettingWithCopyWarning 경고 메시지와 이를 해결하는 방법을 소개하겠습니다.
문제 상황
아래와 비슷한 맥락의 코드를 실행하다가 SettingWithCopyWarning를 만났습니다.
import pandas as pd
# 샘플 데이터 생성
data = {'A': ['apple', 'banana', 'apple', 'grape'],
'B': ['alpha', 'beta', 'gamma', 'delta']}
df = pd.DataFrame(data)
# 'A' 열에서 'apple'인 데이터만 필터링
df_copy = df[df['A'] == 'apple']
# 'B' 열에서 'a'를 제거
df_copy['B'] = df_copy['B'].apply(lambda x: x.replace('a', '') if 'a' in x else x)
SettingWithCopyWarning:
A value is trying to be set on a copy of a slice from a DataFrame.
Try using .loc[row_indexer,col_indexer] = value instead
왜 SettingWithCopyWarning이 발생할까?
경고 메시지는 df에서 'A'가 'apple'인 데이터만 필터링한 후 df_copy에서 값을 수정하려고 하기 때문에 발생합니다. Pandas에서 df[df['A'] == 'apple']을 실행하면, 원본 데이터 df에서 'A' 열이 'apple'인 행들만 선택합니다. 이때, Pandas는 "이 선택된 데이터가 원본 데이터의 일부일까?" 아니면 "완전히 새로운 복사본일까?" 를 확실하게 구분하지 않습니다.
즉, 선택한 데이터(df[df['A'] == 'apple'])가 원본 데이터와 연결된 상태일 수도 있고, 완전히 복사된 데이터일 수도 있습니다. 그래서 선택한 데이터에서 값을 변경하면 원본 데이터도 같이 바뀔 수도 있고, 아닐 수도 있습니다. 이러한 모호한 상황을 방지하기 위해 SettingWithCopyWarning이 발생하는 것입니다.
얕은 복사(shallow copy)와 깊은 복사(deep copy)
좀더 자세히 들여다보면 Pandas에서 df[df['A'] == 'apple']을 실행할 때, 선택된 데이터가 얕은 복사(shallow copy)인지, 깊은 복사(deep copy)인지 명확하지 않은 상태가 됩니다.
- 얕은 복사 (Shallow Copy)
- 선택한 데이터가 원본(df)과 연결된 상태일 수 있음
- 변경하면 원본에도 영향을 줄 수 있음
- 깊은 복사 (Deep Copy)
- 선택한 데이터가 완전히 새로운 복사본일 수도 있음
- 변경해도 원본은 그대로 유지됨
즉, Pandas는 사용자가 df[df['A'] == 'apple']을 만들었을 때,
👉 "이게 원본과 연결된 얕은 복사일 수도 있고, 새로운 깊은 복사일 수도 있는데… 확실하지 않으니까 경고를 띄워야겠다!"
라고 판단하는 것입니다.
해결 방법
1. .loc[ ] 사용하기
어떤 데이터를 바꾸려는 것인지 .loc[ ]을 통해 정확하게 알려준다면 경고가 나오지 않습니다.
# df의 'B' 열을 수정
df.loc[:,'B'] = df['B'].apply(lambda x: x.replace('a', '') if 'a' in x else x)
# df_copy의 'B' 열을 수정
df_copy.loc[:,'B'] = df_copy['B'].apply(lambda x: x.replace('a', '') if 'a' in x else x)
2. .copy() 사용하여 명시적으로 복사하기
df_copy를 만들 때 .copy()를 사용하면 완전히 새로운 데이터로 복사했다고 알려준 것이기 때문에 경고가 나오지 않습니다.
# 'A' 열에서 'apple'인 데이터만 필터링한 새로운 데이터 선언
df_copy = df[df['A'] == 'apple'].copy
# 'B' 열에서 'a'를 제거
df_copy['B'] = df_copy['B'].apply(lambda x: x.replace('a', '') if 'a' in x else x)
SettingWithCopyWarning을 마주친 분들께 도움이 되었으면 좋겠습니다. 오늘도 읽어주셔서 감사합니다.