2014-02-25 6 views
0

을 감안할 때 DataFrame df에 따라 DataFrame 업데이트다른 DataFrame

Id Sex Group Time 
0 21 M  2 2.36 
1 2 F  2 2.09 
2 3 F  1 1.79 

내가 일치 할에 Id, SexGroup 및 중 TimeTime! 업데이트 (에서 update df)와 일치하거나 새 레코드 인 경우 삽입하십시오.

df = df.set_index(['Id', 'Sex', 'Group']) 
update = update.set_index(['Id', 'Sex', 'Group']) 

for i, row in update.iterrows(): 
    if i in df.index: # update 
     df.ix[i, 'Time!'] = row['Time'] 
    else:    # insert new record 
     cols = up.columns.values 
     row = np.array(row).reshape(1, len(row)) 
     _ = pd.DataFrame(row, index=[i], columns=cols) 
     df = df.append(_) 

print df 

       Time Time! 
Id Sex Group    
21 M 2  2.31 2.36 
2 F 2  2.29 2.09 
3 F 1  1.79 NaN 

코드가 제대로 작동하고 내 바란 결과는 위의와 일치 : 여기

내가 그것을 할 방법이다. 그러나, 나는이 조건

if i in df.index: 
    ... 
else: 
    ... 

분명히 잘못된 작업으로, 큰 데이터 세트에 faultily 행동을 발견했습니다 (그것은, 내가 생각 안 else 및 그 구절을 진행 것,이 MultiIndex이 될 수있다 원인을 어떻게 든).

내 질문은, 다른 방법, 또는 더 강력한 버전의 다른 df를 기반으로 한 df를 업데이트 할 수 있습니까?

+0

예상 한 2.09 행에 실수가 있다고 생각합니다. 업데이트에 그룹 = 1이 없습니다. –

+0

예상 출력에 오타가 있다고 생각합니다. 당신이 제공 한 예제에'(2, F, 1)'이 없습니다. – TomAugspurger

+0

OK Andy, 먼저 내 대답을 이기고 지금 내 코멘트 : – TomAugspurger

답변

3

나는 이것을 merge로 할 것이고, 그 다음에 컬럼을 어디에서 갱신 할 것인가라고 생각한다. 처음부터 시간의 열을 제거 :

In [11]: times = up.pop('Time') # up = the update DataFrame 

In [12]: df1 = df.merge(up, how='outer') 

In [13]: df1 
Out[13]: 
    Id Sex Group Time Time! 
0 21 M  2 2.31 NaN 
1 2 F  2 2.29 NaN 
2 3 F  1 NaN NaN 

업데이트 시간을 그것을가 NaN 및 시간이 아니라면! 그것이 NaN 인 경우 :

In [14]: df1['Time!'] = df1['Time'].where(df1['Time'].isnull(), times) 

In [15]: df1['Time'] = df1['Time'].where(df1['Time'].notnull(), times) 

In [16]: df1 
Out[16]: 
    Id Sex Group Time Time! 
0 21 M  2 2.31 2.36 
1 2 F  2 2.29 2.09 
2 3 F  1 1.79 NaN