티스토리 뷰

반응형

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

기타 리소스

 

 

 

 가장 최근 달린 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

반응형
댓글
공지사항
최근에 올라온 글