2016-11-20 2 views
1
팬더에 대한 대체 조건부

나는 다음과 같은 팬더가 DataFrame 있습니다DataFrame

ID COL1 COL2 
123 1  ABC 
123 1  CCC 
123 1  AVV 
345 2  FGG 
345 2  FRG 
345 2  FGT 

:

ID COL1 COL2 
123 1  ABC 
123 1  CCC 
123 NaN AVV 
345 2  FGG 
345 NaN FRG 
345 NaN FGT 

나는이 결과를 얻기 위해 같은 ID에 따라 Col1 모든 NaN의 값을 대체해야 for 루프를 작성할 수는 있지만, 내 데이터 세트가 스크립트를 실행하는 데 오랜 시간이 걸립니다. 조건부 대체 함수가 있습니까?

+0

'df.groupby ('ID') .ffill(). bfill()'이 필요한 것을 제공합니까? – Psidom

+0

@Psidom : 그렇습니다. 고맙습니다. 유일한 문제는 1GB 데이터에 대한 계산을 완료하는 데 오랜 시간이 걸린다는 것입니다. – duckertito

+0

'df.sort_values ​​([ 'ID', 'COL1']) .ffill()'을 시도하면 3 ~ 4 배 더 빠릅니다. 위의 방법보다. NaN 값을 데이터 프레임의 끝으로 정렬하고'ffill()'메서드 만 사용하여 누락 된 값을 채 웁니다. – Psidom

답변

1

시작 : 프로그램 mapping를 구축하려면, 당신은 코드의 두 라인을 사용할 수 있습니다 예 : 다음 :

이 가
df = pd.DataFrame({'ID': list(range(10)), 'COL1': [np.random.choice([1,np.nan]) for _ in range(10)]}) 
df = pd.concat([df]*100000).reset_index(drop = True) 

df.head() 

# COL1 ID 
#0 NaN 0 
#1 1.0 1 
#2 1.0 2 
#3 NaN 3 
#4 1.0 4 

당신은 누락 된 값을 채우기 위해 각 그룹 내에서 방법을 채우기 뒤로 앞으로 채우기를 사용할 수 있습니다 :

%timeit df.groupby('ID').ffill().bfill() 
1 loop, best of 3: 212 ms per loop 

또는 대안 IDCOL1으로 값을 정렬 할 수 있습니다, 이것은 첫째 ID 정렬 각 ID 내에서 COL1을 정렬하여 누락 된 값을 모두 ID 끝에 넣은 다음 ffill(),보다 빠를 것으로 보이는 ffill()을 사용할 수 있습니다. 이 예를 들어 위 (210 개) 방법 : 기타 원치 않는 문자열이있는 경우

%timeit df.sort_values(['ID', 'COL1']).ffill() 
10 loops, best of 3: 71.6 ms per loop 

, 당신은 먼저 NaN으로 문자열을 대체 할 대체 메서드를 호출 할 수 있습니다. 예를 들어, 채우려는 데이터 프레임에 빈 문자열이있는 경우 할 수있어 df.replace('', np.nan).sort_values(['ID', 'COL1']).ffill()

1

Series.isnull()을 사용하여 행을 선택하고 Series.map()을 조건부 대체하려면 어떨까요?

import pandas as pd 
import numpy as np 

df = pd.DataFrame({ 
    'ID': [123, 123, 123, 345, 345, 345], 
    'COL1': [1, 1, np.nan, 2, np.nan, np.nan], 
    'COL2':['ABC', 'CCC', 'AVV', 'FGG', 'FRG', 'FGT']}, 
    columns=['ID','COL1', 'COL2']) 

print df 
mapping = {123: 1, 345: 2} 
df.loc[df['COL1'].isnull(), 'COL1'] = df['ID'].map(mapping) 
print df 

전에 :

후 :

ID COL1 COL2 
0 123 1.0 ABC 
1 123 1.0 CCC 
2 123 1.0 AVV 
3 345 2.0 FGG 
4 345 2.0 FRG 
5 345 2.0 FGT 

편집 :

df_unique = df.loc[df['COL1'].notnull()].groupby('ID').nth(0) 
mapping = pd.Series(df_unique['COL1'].values, index=df_unique.index).to_dict() 
+0

'mapping '을 수동으로 정의해야합니까? – duckertito

+0

자동으로 '매핑'을 만드는 방법을 설명하면 솔루션이 상당히 흥미롭고 유연 해 보입니다. 감사. – duckertito

+0

나는'mapping'의 자동 생성으로 편집을 추가했습니다. 내 코드는 Psidom의 솔루션보다 느린 것으로 생각되지만, 잘하면 그것은 여전히 ​​유용하다. – MarredCheese