Pandas groupby условно, чтобы найти среднее значение столбца timedelta - PullRequest
0 голосов
/ 26 марта 2020

У меня проблемы с получением среднего значения столбца 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     

Я хотел бы создать столбец Avg, взяв среднее значение для каждого пользователя на основе флага Flag ==. Таким образом, данные будут выглядеть так:

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. Руководство ценится.

1 Ответ

1 голос
/ 26 марта 2020

Здесь есть разные проблемы.

  1. Вы хотите вычислить среднее значение для пользователя из подмножества. Хорошо: отфильтруйте соответствующие строки, используйте групповую обработку и получите среднее значение
  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'])
...