2017-11-25 207 views
1

我有一个熊猫数据帧,看起来像这样:熊猫 - GROUPBY连续日期时间段

KEY START  END   VALUE 
0 A  2017-01-01 2017-01-16 2.1 
1 B  2017-01-01 2017-01-23 4.3 
2 B  2017-01-23 2017-02-10 1.7 
3 A  2017-01-28 2017-02-02 4.2 
4 A  2017-02-02 2017-03-01 0.8 

我想groupbyKEYsumVALUE但仅限于时间连续句。因为在该时间段的空隙

A
KEY START  END   VALUE 
0 A 2017-01-01 2017-01-16 2.1 
1 A 2017-01-28 2017-03-01 5.0 
2 B 2017-01-01 2017-02-10 6.0 

有二组:比如在上面的例子中,我想获得。 我想避免循环,因为数据帧有数千万行。

回答

1

创建由每组比较shiftSTART列,并用它来groupby帮手Series

s = df.loc[df.groupby('KEY')['START'].shift(-1) == df['END'], 'END'] 
s = s.combine_first(df['START']) 
print (s) 
0 2017-01-01 
1 2017-01-23 
2 2017-01-23 
3 2017-02-02 
4 2017-02-02 
Name: END, dtype: datetime64[ns] 

df = df.groupby(['KEY', s], as_index=False).agg({'START':'first','END':'last','VALUE':'sum'}) 
print (df) 
    KEY VALUE  START  END 
0 A 2.1 2017-01-01 2017-01-16 
1 A 5.0 2017-01-28 2017-03-01 
2 B 6.0 2017-01-01 2017-02-10 
+0

谢谢。但是,这一次只汇集两行。任何想法如果我有与原始问题中描述的相同的数据框,再加上'START'= 2017-03-01和'2017-03-31'为'END'的附加行,我可以如何修改您的解决方案?在这种情况下,从2017-01-28到2017-03-31有一个完全连续的时期,3行应该汇总在一起。 – Prikers

+0

不是那么容易,我尝试找到解决方案,但如果需要更快,您能创建新问题吗? – jezrael

0

从jezrael答案就像一个魅力,如果有只聚合两个连续的行。在新示例中,它不会聚合KEY = A的最后三行。

 KEY START  END   VALUE 
0 A  2017-01-01 2017-01-16 2.1 
1 B  2017-01-01 2017-01-23 4.3 
2 B  2017-01-23 2017-02-10 1.7 
3 A  2017-01-28 2017-02-02 4.2 
4 A  2017-02-02 2017-03-01 0.8 
5 A  2017-03-01 2017-03-23 1.0 

以下解决方案(jezrael的解决方案稍作修改)使聚合应累计的所有行:

df = df.sort_values(by='START') 
idx = df.groupby('KEY')['START'].shift(-1) != df['END'] 
df['DATE'] = df.loc[idx, 'START'] 
df['DATE'] = df.groupby('KEY').DATE.fillna(method='backfill') 
df = (df.groupby(['KEY', 'DATE'], as_index=False) 
     .agg({'START': 'first', 'END': 'last', 'VALUE': 'sum'}) 
     .drop(['DATE'], axis=1)) 

其中给出:

KEY START   END  VALUE 
0 A 2017-01-01 2017-01-16 2.1 
1 A 2017-01-28 2017-03-23 6.0 
2 B 2017-01-01 2017-02-10 6.0 

感谢@jezrael为优雅接近!