2016-08-02 4 views
1

두 개의 팬더 데이터 프레임 (X 및 Y)이 있고 부울 값으로 부울 값을 채우려고합니다. X의 축과 Y의 열/구성 요소 사이의 상호 관계. 중첩 루프를 통해이 작업을 수행 할 수 있었고 코드는 장난감 예제에서 작동하지만 실제 데이터 세트에는 너무 느립니다.다른 데이터 프레임의 열 머리글 멤버십을 기반으로 한 팬더 데이터 프레임의 부울 값 설정 (날짜순)

# define X, Y and Z 
idx=pd.date_range('2016-1-31',periods=3,freq='M') 
codes = list('ABCD') 
X = np.random.randn(3,4) 
X = pd.DataFrame(X,columns=codes,index=idx) 

Y = [['A','A','B'],['C','B','C'],['','C','D']] 
Y = pd.DataFrame(Y,columns=idx) 

Z = pd.DataFrame(columns=X.columns, index=X.index) 

이 예제에서 X의 색인은 Y의 열과 일치합니다. 실제 예에서 Y의 열은 X의 인덱스의 하위 집합입니다.

Z의 축은 X와 같습니다. 다음과 같이 내가 Z의 열 헤더는 헤더와 Y의 열에서 Z. 내 작업 코드의 인덱스에 동일한 경우는 true와 Z의 요소를 채울 수 있습니다 원하는 :

for r in Y: 
    for c in Z: 
     Z.loc[r,c] = c in Y[r].values 

를 코드는 매우 깨끗하고 짧지 만 더 큰 데이터 세트를 실행하는 데 오랜 시간이 걸립니다. 나는 훨씬 더 빨리 달성하기 위해 vectorised 방법이 있기를 바라고있다.

도움이 될 것입니다.

고마워요!

답변

1

stack 메서드를 사용할 수 있습니다. 여기서 DataFrame의 값은 DataFrames의 값으로 열과 열로 변환됩니다. notnull에 의해 마지막 테스트 NaN :

print (Y.replace({'':np.nan}) 
     .stack() 
     .reset_index(0) 
     .set_index(0, append=True) 
     .squeeze() 
     .unstack() 
     .rename_axis(None, axis=1) 
     .notnull()) 

       A  B  C  D 
2016-01-31 True False True False 
2016-02-29 True True True False 
2016-03-31 False True True True 

pivot 또 다른 솔루션 : 코멘트에 의해

print (Y.replace({'':np.nan}) 
     .stack() 
     .reset_index(name='a') 
     .pivot(index='level_1', columns='a', values='level_0') 
     .rename_axis(None, axis=1) 
     .rename_axis(None)   
     .notnull()) 

       A  B  C  D 
2016-01-31 True False True False 
2016-02-29 True True True False 
2016-03-31 False True True True 

편집 :

사용 reindex 인덱스가 고유하고 fillnaFalse에 의한 경우 :

import pandas as pd 
import numpy as np 

# define X, Y and Z 
idx=pd.date_range('2016-1-31',periods=5,freq='M') 
codes = list('ABCD') 
X = np.random.randn(5,4) 
X = pd.DataFrame(X,columns=codes,index=idx) 

Y = [['A','A','B'],['C','B','C'],['','C','D']] 
Y = pd.DataFrame(Y,columns=idx[:3]) 
Z = pd.DataFrame(columns=X.columns, index=X.index) 

print (X) 
        A   B   C   D 
2016-01-31 0.810348 -0.737780 -0.523869 -0.585772 
2016-02-29 -1.126655 -0.494999 -1.388351 0.460340 
2016-03-31 -1.578155 0.950643 -1.699921 1.149540 
2016-04-30 -2.320711 1.263740 -1.401714 0.090788 
2016-05-31 1.218036 0.565395 0.172278 0.288698 

print (Y) 
    2016-01-31 2016-02-29 2016-03-31 
0   A   A   B 
1   C   B   C 
2      C   D 

print (Z) 
       A B C D 
2016-01-31 NaN NaN NaN NaN 
2016-02-29 NaN NaN NaN NaN 
2016-03-31 NaN NaN NaN NaN 
2016-04-30 NaN NaN NaN NaN 
2016-05-31 NaN NaN NaN NaN 
Y1 = Y.replace({'':np.nan}) 
     .stack() 
     .reset_index(name='a') 
     .pivot(index='level_1', columns='a', values='level_0') 
     .rename_axis(None, axis=1) 
     .rename_axis(None) 
     .notnull() 
print (Y1) 
       A  B  C  D 
2016-01-31 True False True False 
2016-02-29 True True True False 
2016-03-31 False True True True 

print (Y1.reindex(X.index).fillna(False)) 
       A  B  C  D 
2016-01-31 True False True False 
2016-02-29 True True True False 
2016-03-31 False True True True 
2016-04-30 False False False False 
2016-05-31 False False False False 
+0

감사합니다. Z가 X와 같은 축 (Y의 축은 하위 집합 임)을 갖도록하려는 점에서 나머지 문제가 하나 있습니다. 패널 내에서 X 및 Z 데이터 프레임을 만들면 NaN에 의해 ​​채워진 나머지 요소가 자동으로 생성됩니다. 패널을 사용하지 않았다면 위의 결과를 X와 동일한 축으로 어떻게 확장 할 수 있습니까? 예를 들어, X가 색인에 두 개의 추가 행이있는 경우 – tmasters

관련 문제