Pandas获得组内的平均时间间隔

时间:2017-02-26 22:23:13

标签: python pandas dataframe

我有一个包含EffectiveDate列的DataFrame。 我想通过Key值对DataFrame进行分组,然后计算EffectiveDate列的每个组中所有日期值的平均时间间隔。

例如,对于DataFrame:

    EffectiveDate
1   2015-08-17 07:00:00
1   2015-08-18 07:00:00
1   2015-08-19 07:00:00
2   2015-08-20 07:00:00
2   2015-08-21 07:00:00
2   2015-09-16 07:00:00
2   2015-10-15 07:00:00
2   2015-11-16 08:00:00

我想通过索引进行分组,并计算EffectiveDate列中日期值之间的平均间隔。

15199   2015-08-17 07:00:00
15214   2015-08-18 07:00:00
15219   2015-08-19 07:00:00
15233   2015-08-20 07:00:00
15254   2015-08-21 07:00:00
15687   2015-09-16 07:00:00
199     2015-10-15 07:00:00
1123    2015-11-16 08:00:00
Name: EffectiveDate, dtype: datetime64[ns]

在单个系列上,这似乎工作正常:

EffectiveDate.diff().astype('timedelta64[s]').mean()

但是当我在pandas DataFrame上使用与groupby聚合相同的函数时:

df.groupby('Key').agg({
    'EffectiveDate': lambda x: x.diff().astype('timedelta64[s]').mean()
})

结果

                  EffectiveDate                               
1 1970-01-01 00:00:00.016747425
2 1970-01-01 00:00:00.017765280
3 1970-01-01 00:00:00.034776096
4 1970-01-01 00:00:00.002052450
5 1970-01-01 00:00:00.018238800
6 1970-01-01 00:00:00.024005438 
7 1970-01-01 00:00:00.012330000

我希望每列中都有一个整数字段。我正在使用Pandas 0.19.2

1 个答案:

答案 0 :(得分:2)

GroupBy.agg似乎试图将 back 强制转换为0.19.2中EffectiveDate列的原始dtype。通常我认为这可能有意义,因为我们希望列中的聚合具有相同的dtype。

要解决此问题,您可以在0.19.2中使用GroupBy.apply,之后不会执行相同的演员。

df.groupby(df.index).apply(
    lambda x: x.diff().astype('timedelta64[s]').mean()
)

似乎以前没有这种情况,因为只有在将转换为 EffectiveDate列的原始dtype之后,我才能在0.18.1中重现您的行为。

0.18.1

>>> df
        EffectiveDate
1 2015-08-17 07:00:00
1 2015-08-18 07:00:00
1 2015-08-19 07:00:00
2 2015-08-20 07:00:00
2 2015-08-21 07:00:00
2 2015-09-16 07:00:00
2 2015-10-15 07:00:00
2 2015-11-16 08:00:00

>>> df.groupby(df.index).agg({
        'EffectiveDate': lambda x: x.diff().astype('timedelta64[s]').mean()
})

   EffectiveDate
1        86400.0
2      1901700.0

>>> df.groupby(df.index).agg({
        'EffectiveDate': lambda x: x.diff().astype('timedelta64[s]').mean()
}).astype(df.EffectiveDate.dtype)

                  EffectiveDate
1 1970-01-01 00:00:00.000086400
2 1970-01-01 00:00:00.001901700