2015-08-31 43 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'] 

有什麼想法?