2014-02-25 235 views
0

鉴于数据帧df一个数据帧:更新基于另一个数据框

Id Sex Group Time Time! 
0 21 M  2 2.31 NaN 
1 2 F  2 2.29 NaN 

update

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

我想匹配IdSexGroup,要么更新Time!Time值(从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 

的代码似乎工作,我想结果与上述一致。不过,我已经注意到了这个faultily表现上了一个大的数据集,与条件

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

工作显然是错误的(它会继续else和副诗句,它应该不会,我想,这多指标可能不知何故)。

所以我的问题是,你知道任何其他方式,或更强大的版本,我更新一个DF基于另一个DF?

+0

我认为您的预期存在一个错误,2.09行在更新中没有组= 1。 –

+0

我认为你的预期产出有一个错字顺便说一句。在你提供的例子中没有'(2,F,1)' – TomAugspurger

+0

确定Andy,首先你击败我的回答,现在我的评论:) – TomAugspurger

回答

3

我想我会用合并来做到这一点,然后用where来更新列。首先删除时间列:

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