2015-08-31 41 views
1

2个DataFrames我有一个查找表(LUT)数据帧在结构上类似于如下:大熊猫的GroupBy定义与自定义功能

ID Date   ColOne 
AAAA 2010-07-06 ... 
AAAA 2011-12-31 ... 
AAAA 2013-02-15 ... 
AAAA 2015-05-21 ... 
AAAB 2008-01-08 ... 
AAAB 2010-10-20 ... 
AAAB 2014-03-31 ... 
... 

几千年的ID。我有另一个DataFrame(REF)中包含的数据,我想有效折叠到上面的LUT中。在结构上,酷似REF:

ID Date   RefVal 
AAAA 2009-01-01 Val1 
AAAA 2013-05-21 Val2 
AAAB 2009-03-02 Val3 
AAAB 2012-09-09 Val4 
AAAB 2013-12-31 Val5 
... 

特别是,我想向RefVal值REF到LUT基于值出现在REF和LUT日期为每个ID。例如所产生的LUT可能看起来像:

ID Date  ColOne RefVal 
AAAA 2010-07-06 ...  Val1 
AAAA 2011-12-31 ...  Val1 
AAAA 2013-02-15 ...  Val1 
AAAA 2015-05-21 ...  Val2 
AAAB 2008-01-08 ...  NaN 
AAAB 2010-10-20 ...  Val3 
AAAB 2014-03-31 ...  Val5 

换句话说,在ReFVal在LUT将是RefVal最近报告该ID。更多解释:

  • 由于REF中的下一个条目在AAAA的前三个条目之后有一个日期,因此Val1出现三次;
  • Val2仅出现在最后一个条目中,因为那是该日期在AAAA的REF2中Val2的日期之后的唯一条目;
  • NaN出现在AAAB的第一行,因为没有在LUT中的第一个条目之前的日期的RefVal;
  • Val4从未出现,因为Val4在Val5的AAAB日期之前没有日期。

我相信,一个自定义功能可以定义和使用类似应用于LUT:

LUT['RefVal'] = LUT.groupby('ID').apply(lambda x: fun(x)) 

但我不知道该怎么写功能,因为它必须引用另一个数据框,并使用我正在分组的ID。有什么想法吗?

回答

1

ordered_merge功能可能是你追求的:

 ID  Date ColOne RefVal 
0 AAAA 2009-01-01  ... Val1 
1 AAAA 2010-07-06  ... Val1 
2 AAAA 2011-12-31  ... Val1 
3 AAAA 2013-02-15  ... Val1 
4 AAAA 2013-05-21  ... Val2 
5 AAAA 2015-05-21  ... Val2 
6 AAAB 2008-01-08  ... Val2 
7 AAAB 2009-03-02  ... Val3 
8 AAAB 2010-10-20  ... Val3 
9 AAAB 2012-09-09  ... Val4 
10 AAAB 2013-12-31  ... Val5 
11 AAAB 2014-03-31  ... Val5 
+1

好主意@crow_t_robot!我制定了一个解决方案,使用下面的结果。它适用于我上面的示例,但我不确定是否有更好的方法来处理它。有什么想法吗? – DrTRD

1

这里有一个建议的答案:

df1 = LUT.set_index(['ID','Date']).copy() 
df2 = REF.set_index(['ID','Date']).copy() 
merged = pd.concat([df1a, df2a]).sort() 
merged = merged.reset_index() 

现在应用ffill拉姆达在

df1.sort('Date', ascending=False) 
df2.sort('Date', ascending=False) 
res= pd.ordered_merge(df1, df2, fill_method='ffill') 

结果如下:

merged['RefVal'] = merged.groupby('ID')['RefVal'].transform(lambda x: x.ffill()) 
LUT['RefVal'] = merged.loc[LUT.index,'RefVal'] 

有什么想法?