【问题标题】:Pandas groupby conditional to find mean of timedelta columnPandas groupby 有条件地查找 timedelta 列的平均值
【发布时间】:2020-07-07 07:01:14
【问题描述】:

我无法获取 timedelta 列的平均值。

我的数据如下所示:

user          date           Flag    Value        
0    ron  12/23/2016        'flag'    0 days 10:08:00     
1    ron  12/21/2016        'n/a'     0 days 08:00:00      
2    ron   12/23/2016       'flag'    0 days 10:08:00     
3    ron  12/21/2016        'n/a'     0 days 02:00:00      
4   andy   12/22/2016       'flag'    0 days 10:00:00     
5   andy   12/22/2016       'flag'    0 days 10:00:00     

我想通过根据 Flag==flag 获取每个用户的 Value 的平均值来生成 Avg 列。所以数据应该是这样的:

user          date           Flag    Value                   Avg
0    ron  12/23/2016        'flag'    0 days 10:08:00     0 days 10:08:00
1    ron  12/21/2016        'n/a'     0 days 08:00:00     0 days 10:08:00
2    ron   12/23/2016       'flag'    0 days 10:08:00     0 days 10:08:00
3    ron  12/21/2016        'n/a'     0 days 02:00:00     0 days 10:08:00
4   andy   12/22/2016       'flag'    0 days 10:00:00     0 days 10:00:00
5   andy   12/22/2016       'flag'    0 days 10:00:00     0 days 10:00:00

我有这段代码会产生数据错误:

sample.loc[:,'Value'] = pd.to_timedelta(sample['Value'])
sample.loc[:,'Avg'] = sample['user'].map(sample[sample['Flag']=='flag'].groupby('user')['Value'].mean())

但这是我得到的错误:

DataError: No numeric types to aggregate

我不确定当我将 Value 转换为 timedelta 时为什么会这样说。指导表示赞赏。

【问题讨论】:

标签: python pandas group-by transform timedelta


【解决方案1】:

这里有不同的问题。

  1. 您希望从子集中计算每个用户的平均值。好的:过滤相关行,使用 groupby 和 mean
  2. 您希望将该值应用于用户的所有值。正常的方法是在 groupby 之前用原始索引重新索引,并在 groupby 之后使用变换
  3. 您正在处理 Timedelta 列。您必须将其转换为数字列。这里的诀窍是你应该使用整数类型但希望能够使用 NaN 值,所以我们必须转换两次,第一次转换为 int64,然后转换为 float64

它终于给出了:

df['mean'] = pd.to_timedelta(df.loc[df['Flag'] == "'flag'", 'Value']
                             .astype('int64').astype('float64')
                             .reindex(df.index).groupby(df['user'])
                             .transform('mean'))

它给出:

   user       date    Flag    Value     mean
0   ron 2016-12-23  'flag' 10:08:00 10:08:00
1   ron 2016-12-21   'n/a' 08:00:00 10:08:00
2   ron 2016-12-23  'flag' 10:08:00 10:08:00
3   ron 2016-12-21   'n/a' 02:00:00 10:08:00
4  andy 2016-12-22  'flag' 10:00:00 10:00:00
5  andy 2016-12-22  'flag' 10:00:00 10:00:00

注意:以上假设 Value 的数据类型是 timedelta64[ns] (pd.Timedelta)。如果没有,您必须先将其转换为 Timedelta :

df['Value'] = pd.to_timedelta(df['Value'])

【讨论】:

  • 如果 NaT 值存在于 Value 列中,我该如何考虑它们?
  • 不确定这是否是正确的评论方式,但我发现如果我添加 'dropna().astype('int64')' 就可以了,非常感谢您抽出宝贵的时间跨度>
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2021-10-20
  • 2022-01-24
相关资源
最近更新 更多