티스토리 뷰
Stack Overflow에 자주 검색, 등록되는 문제들과 제가 개발 중 찾아 본 문제들 중에서 나중에도 찾아 볼 것 같은 문제들을 정리하고 있습니다.
Stack Overflow에서 가장 먼저 확인하게 되는 가장 높은 점수를 받은 Solution과 현 시점에 도움이 될 수 있는 가장 최근에 업데이트(최소 점수 확보)된 Solution을 각각 정리하였습니다.
아래 word cloud를 통해 이번 포스팅의 주요 키워드를 미리 확인하세요.
How to deal with SettingWithCopyWarning in Pandas
Pandas에서 SettingWithCopyWarning을 처리하는 방법
문제 내용
Background
배경
I just upgraded my Pandas from 0.11 to 0.13.0rc1. Now, the application is popping out many new warnings. One of them like this:
나는 방금 내 팬더를 0.11에서 0.13.0rc1로 업그레이드했습니다. 이제, 그 애플리케이션은 많은 새로운 경고들을 쏟아내고 있습니다. 그들 중 하나는 다음과 같다:
E:\FinReporter\FM_EXT.py:449: SettingWithCopyWarning: A value is trying to be set on a copy of a slice from a DataFrame.
Try using .loc[row_index,col_indexer] = value instead
quote_df['TVol'] = quote_df['TVol']/TVOL_SCALE
I want to know what exactly it means? Do I need to change something?
그게 정확히 무슨 뜻인지 알고 싶어요? 뭔가 바꿔야 하나요?
How should I suspend the warning if I insist to use quote_df['TVol'] = quote_df['TVol']/TVOL_SCALE
?
quote_df['TVol'] = quote_df['TVol']/TVOL_SCALE 을 경고 없이 사용하려면 어떻게 해야하나요?
The function that gives errors
오류를 발생시키는 함수
def _decode_stock_quote(list_of_150_stk_str):
"""decode the webpage and return dataframe"""
from cStringIO import StringIO
str_of_all = "".join(list_of_150_stk_str)
quote_df = pd.read_csv(StringIO(str_of_all), sep=',', names=list('ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefg')) #dtype={'A': object, 'B': object, 'C': np.float64}
quote_df.rename(columns={'A':'STK', 'B':'TOpen', 'C':'TPCLOSE', 'D':'TPrice', 'E':'THigh', 'F':'TLow', 'I':'TVol', 'J':'TAmt', 'e':'TDate', 'f':'TTime'}, inplace=True)
quote_df = quote_df.ix[:,[0,3,2,1,4,5,8,9,30,31]]
quote_df['TClose'] = quote_df['TPrice']
quote_df['RT'] = 100 * (quote_df['TPrice']/quote_df['TPCLOSE'] - 1)
quote_df['TVol'] = quote_df['TVol']/TVOL_SCALE
quote_df['TAmt'] = quote_df['TAmt']/TAMT_SCALE
quote_df['STK_ID'] = quote_df['STK'].str.slice(13,19)
quote_df['STK_Name'] = quote_df['STK'].str.slice(21,30)#.decode('gb2312')
quote_df['TDate'] = quote_df.TDate.map(lambda x: x[0:4]+x[5:7]+x[8:10])
return quote_df
More error messages
더 많은 오류 메시지
E:\FinReporter\FM_EXT.py:449: SettingWithCopyWarning: A value is trying to be set on a copy of a slice from a DataFrame.
Try using .loc[row_index,col_indexer] = value instead
quote_df['TVol'] = quote_df['TVol']/TVOL_SCALE
E:\FinReporter\FM_EXT.py:450: SettingWithCopyWarning: A value is trying to be set on a copy of a slice from a DataFrame.
Try using .loc[row_index,col_indexer] = value instead
quote_df['TAmt'] = quote_df['TAmt']/TAMT_SCALE
E:\FinReporter\FM_EXT.py:453: SettingWithCopyWarning: A value is trying to be set on a copy of a slice from a DataFrame.
Try using .loc[row_index,col_indexer] = value instead
quote_df['TDate'] = quote_df.TDate.map(lambda x: x[0:4]+x[5:7]+x[8:10])
높은 점수를 받은 Solution
The SettingWithCopyWarning
was created to flag potentially confusing "chained" assignments, such as the following, which does not always work as expected, particularly when the first selection returns a copy. [see GH5390 and GH5597 for background discussion.]
SettingWithCopyWarning은 다음과 같이 혼란스러울 수 있는 "연쇄된" 할당에 플래그를 표시하기 위해 만들어졌으며, 특히 첫 번째 선택이 복사본을 반환할 때 항상 예상대로 작동하지는 않습니다. (배경 논의는 GH5390 및 GH5597 참조).
df[df['A'] > 2]['B'] = new_val # new_val not set in df
The warning offers a suggestion to rewrite as follows:
경고는 다음과 같이 다시 작성할 것을 제안합니다.
df.loc[df['A'] > 2, 'B'] = new_val
However, this doesn't fit your usage, which is equivalent to:
그러나 이는 다음과 같은 용도에 맞지 않습니다.
df = df[df['A'] > 2]
df['B'] = new_val
While it's clear that you don't care about writes making it back to the original frame (since you are overwriting the reference to it), unfortunately this pattern cannot be differentiated from the first chained assignment example. Hence the (false positive) warning. The potential for false positives is addressed in the docs on indexing, if you'd like to read further. You can safely disable this new warning with the following assignment.
원래 프레임에 대한 참조를 덮어쓰므로 쓰기 작업에 신경 쓰지 않는 것은 분명하지만 불행히도 이 패턴은 처음 연결된 할당 예제와 구별할 수 없습니다. 따라서 (거짓 양성) 경고입니다. 잘못된 긍정의 가능성은 인덱싱에 대한 문서에서 자세히 설명합니다. 다음 할당을 통해 이 새 경고를 안전하게 비활성화할 수 있습니다.
import pandas as pd
pd.options.mode.chained_assignment = None # default='warn'
Other Resources
기타 리소스
- pandas User Guide: Indexing and selecting data
- Python Data Science Handbook: Data Indexing and Selection
- Real Python: SettingWithCopyWarning in Pandas: Views vs Copies
- Dataquest: SettingwithCopyWarning: How to Fix This Warning in Pandas
- Towards Data Science: Explaining the SettingWithCopyWarning in pandas
가장 최근 달린 Solution
In my case, I would create a new column based on the index, but I got the same warning as you:
내 경우에는 인덱스를 기반으로 새 열을 생성하지만 다음과 같은 경고가 표시됩니다.
df_temp["Quarter"] = df_temp.index.quarter
I use insert() instead of direct assignment, and it works for me:
나는 직접 할당 대신 insert()를 사용하는데, 이것은 나에게 효과가 있습니다:
df_temp.insert(loc=0, column='Quarter', value=df_temp.index.quarter)
출처 : https://stackoverflow.com/questions/20625582/how-to-deal-with-settingwithcopywarning-in-pandas
'개발 > 파이썬' 카테고리의 다른 글
로컬 폴더의 모든 파일 삭제하기 (0) | 2022.12.08 |
---|---|
리스트에서 아이템 무작위로 선택하기 (0) | 2022.12.08 |
기존 Pandas 데이터 프레임에 새 열을 추가하기 (0) | 2022.12.07 |
빈 Pandas 데이터프레임 만든 후 한 행씩 추가하기 (0) | 2022.12.07 |
Pandas DataFrame 열 전체 리스트 가져오기 (0) | 2022.12.06 |