按组计算 datetime64 的平均值

2 投票
3 回答
2119 浏览
提问于 2025-04-18 10:30

我该如何在分组后计算平均日期呢?

import pandas as pd
import numpy as np
df = pd.DataFrame ({'ID' : ['foo', 'bar'] * 5,
               'VAL' : pd.date_range(start='4/1/2012', periods=10)})


ID  VAL
    foo 2012-04-01 00:00:00
    bar 2012-04-02 00:00:00
    bar 2012-04-04 00:00:00
    foo 2012-04-05 00:00:00
    bar 2012-04-06 00:00:00
    foo 2012-04-07 00:00:00
    bar 2012-04-08 00:00:00
    foo 2012-04-09 00:00:00
    bar 2012-04-10 00:00:00

我想要的结果是:

bar 06/04/2012
foo 05/04/2012

我该怎么做呢?

3 个回答

0

可能有更有效的方法,但一种做法是先把时间转换成一个数字,然后计算这些数字的平均值,最后再把结果转换回时间格式。

In [264]: df['VAL_ordinal'] = df['VAL'].apply(lambda x: x.toordinal())

In [267]: df.groupby('ID')['VAL_ordinal'].mean().apply(lambda x: datetime.fromordinal(int(x)))
Out[267]: 
ID
bar   2012-04-06
foo   2012-04-05
Name: VAL_ordinal, dtype: datetime64[ns]
3

这段话的意思是,先计算一系列时间差的平均值,然后再把这个平均值加回到起始日期上。等到0.14.1版本(很快就会发布)时,这个过程会变得更简单,因为你可以直接对一个时间差的数组求平均。

In [10]: m = df['VAL'].min()

In [11]: df.groupby('ID')['VAL'].apply(lambda x: (x-m).mean())+m
Out[11]: 
ID    
bar  0   2012-04-06
foo  0   2012-04-05
dtype: datetime64[ns]
4

这里有一个替代的方法,就是把日期时间的值当作整数(int64)来看,这样存储和转换会更简单:

In [11]: df['VAL'].astype('int64').groupby(df['ID']).mean().astype('datetime64[ns]')
Out[11]:
ID
bar   2012-04-06
foo   2012-04-05
dtype: datetime64[ns]

因为我们在这里使用的是视图,这样应该比使用apply更高效、更快...

正如Jeff所指出的:这个问题在主版本中已经修复了(所以在0.14.1版本中也修复了):

df.groupby('ID').mean()

应该“直接就能用”。

撰写回答