2014-04-08 6 views
5

해당 열 중 하나에 함수를 적용하고 동일한 열에 결과를 할당하려는 MultiIndex pandas DataFrame이 있습니다. 나는이 경고를 얻을 수 있기 때문에 당신이 볼 수 있듯이MultiIndex pandas.DataFrame 열에 함수 적용

In [1]: 
    import numpy as np 
    import pandas as pd 
    cols = ['One', 'Two', 'Three', 'Four', 'Five'] 
    df = pd.DataFrame(np.array(list('ABCDEFGHIJKLMNO'), dtype='object').reshape(3,5), index = list('ABC'), columns=cols) 
    df.to_hdf('/tmp/test.h5', 'df') 
    df = pd.read_hdf('/tmp/test.h5', 'df') 
    df 
Out[1]: 
     One  Two  Three Four Five 
    A A  B  C  D  E 
    B F  G  H  I  J 
    C K  L  M  N  O 
    3 rows × 5 columns 

In [2]: 
    df.columns = pd.MultiIndex.from_arrays([list('UUULL'), ['One', 'Two', 'Three', 'Four', 'Five']]) 
    df['L']['Five'] = df['L']['Five'].apply(lambda x: x.lower()) 
    df 
-c:2: 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 
Out[2]: 
     U      L 
     One Two  Three Four Five 
    A A  B  C  D  E 
    B F  G  H  I  J 
    C K  L  M  N  O 
    3 rows × 5 columns 

In [3]: 
    df.columns = ['One', 'Two', 'Three', 'Four', 'Five'] 
    df  
Out[3]: 
     One Two  Three Four Five 
    A A  B  C  D  E 
    B F  G  H  I  J 
    C K  L  M  N  O 
    3 rows × 5 columns 

In [4]: 
    df['Five'] = df['Five'].apply(lambda x: x.upper()) 
    df 
Out[4]: 
     One Two  Three Four Five 
    A A  B  C  D  E 
    B F  G  H  I  J 
    C K  L  M  N  O 
    3 rows × 5 columns 

, 함수가 열에 적용되지 않는 것 같아요 :

-c:2: 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 

어떤 이상한 것은이 오류는 종종 발생, 나는 천국이다 그 일이 언제 언제 일어나는지를 이해할 수 없었습니다. 경고가 권장하는

나는 .loc으로 dataframe 슬라이스 기능을 적용 할 관리 :

In [5]: 
    df.columns = pd.MultiIndex.from_arrays([list('UUULL'), ['One', 'Two', 'Three', 'Four', 'Five']]) 
    df.loc[:,('L','Five')] = df.loc[:,('L','Five')].apply(lambda x: x.lower()) 
    df 

Out[5]: 
     U      L 
     One Two  Three Four Five 
    A A  B  C  D  e 
    B F  G  H  I  j 
    C K  L  M  N  o 
    3 rows × 5 columns 

을하지만이 동작이 DICT 같은 슬라이스를 수행 할 때 발생하는 이유를 이해하고자하는 (예를 들어 df['L']['Five']을)와하지 않을 때 .loc 슬라이싱을 사용합니다.

참고 : DataFrame은 멀티 인덱싱되지 않은 HDF 파일에서 가져온 것일 수 있습니다. 이것은 아마 이상한 동작의 원인입니까?

EDIT : 나는 값이 'L'다음 열의 다섯 '가 선택되는 DataFrame를 반환하는 액세스 시리즈 복귀 가진 레벨 0을 선택한다 Pandas v.0.13.1

답변

5

df['L']['Five']NumPy v.1.8.0 사용하고 .

Dataframe 용 __getitem__ 접근 자 ([])는 올바른 작업을 수행하고 올바른 열을 제공합니다. 그러나이 색인은 연속 된 색인입니다. see here

다중 색인에 액세스하려면 터플 표기법 ('a','b').loc을 명확하게 사용하십시오 (예 : df.loc[:,('a','b')]. 또한 동시에 여러 축 인덱싱 (예 : 행 및 열)이 가능합니다.

그러면 색인 생성 및 할당을 체인화 할 때 왜이 기능이 작동하지 않습니까? df['L']['Five'] = value.

df['L']은 단일 색인화 된 데이터 프레임을 다시 표시합니다. 그런 다음 다른 파이썬 연산 df_with_L['Five']이 'Five'에 의해 시리즈 인덱스를 선택합니다. 나는 이것을 또 다른 변수로 지적했다. 팬더는 별도의 이벤트와 같은 이러한 작업 (__getitem__에 예를 들어 별도의 호출을보고, 그래서 선형 작업로 처리하기 때문에, 그들은 잇달아 발생합니다. 단일 통화에 (:,('L','Five'))의 중첩 된 튜플을 통과 df.loc[:,('L','Five')]

명암이 __getitem__. 팬더는 이것을 단일 엔티티로 처리 할 수 ​​있습니다 (프레임에 직접 색인 할 수 있기 때문에 꽤 빠릅니다).

왜 그런가요? 연결된 색인은 2 통화이므로, 두 호출 중 하나가 슬라이스 방식으로 인해 복사본을 반환 할 수 있습니다. 따라서이 값을 설정하면 실제로 복사본을 설정하고 원래 프레임. 판다가 연결되어 있지 않은 2 개의 파이썬 연산이기 때문에 판다가 이것을 이해하는 것은 불가능합니다.

경고는 '발견 적'이며이를 감지합니다 (대부분의 경우를 파악하는 경향이 있음을 의미하는 것은 간단한 검사입니다). 실제 상황을 파악하는 것은 복잡합니다.

.loc 작업은 단일 파이썬 작업이므로 슬라이스 (여전히 사본 일 수 있음)를 선택할 수 있지만 팬더가 수정 된 후 해당 슬라이스를 다시 프레임에 할당하여 사용자가 원하는대로 값을 설정할 수 있습니다 생각한다.

경고의 이유는 다음과 같습니다. 가끔 어레이를 슬라이스 할 때 뷰를 다시 얻으므로 아무 문제가 없도록 설정할 수 있습니다. 그러나 단일 dtyped 배열 특정 방법으로 잘라낸 경우 복사본을 생성 할 수 있습니다. 멀티 dtyped DataFrame (즉, float 및 object 데이터를 말함)은 거의 항상 사본을 생성합니다. 뷰의 작성 여부는 배열의 메모리 레이아웃에 따라 다릅니다.

참고 :이 정보는 데이터 출처와 관련이 없습니다.

+1

정말이 설명이 마음에 들었습니다 ... 우리가 문서에서 비슷한 것을 알고 있지만이 책은 더 좋은 산문을 가지고 있습니다. 'pd.merge (orig_doc, this_explanation, how = 'right')'를 할 수 있을까요? :) –

+0

업데이트 : http://pandas-docs.github.io/pandas-docs-travis/indexing.html#returning-a-view-versus-a-copy – Jeff