Поиск среднего и стандартного отклонения объекта timedelta в pandas df

Я хотел бы рассчитать mean и standard deviation timedelta по банкам из dataframe с двумя столбцами, показанными ниже. Когда я запускаю код (также показанный ниже), я получаю следующую ошибку:

pandas.core.base.DataError: No numeric types to aggregate

Мой фрейм данных:

   bank                          diff
   Bank of Japan                 0 days 00:00:57.416000
   Reserve Bank of Australia     0 days 00:00:21.452000
   Reserve Bank of New Zealand  55 days 12:39:32.269000
   U.S. Federal Reserve          8 days 13:27:11.387000

Мой код:

means = dropped.groupby('bank').mean()
std = dropped.groupby('bank').std()

Ответ 1

Вам необходимо преобразовать timedelta в некоторое числовое значение, например int64 по values которые являются наиболее точными, потому что преобразование в ns - это то, что является числовым представлением timedelta:

dropped['new'] = dropped['diff'].values.astype(np.int64)

means = dropped.groupby('bank').mean()
means['new'] = pd.to_timedelta(means['new'])

std = dropped.groupby('bank').std()
std['new'] = pd.to_timedelta(std['new'])

Другое решение - преобразовать значения в seconds по total_seconds, но это менее точно:

dropped['new'] = dropped['diff'].dt.total_seconds()

means = dropped.groupby('bank').mean()

Ответ 2

Не нужно конвертировать timedelta туда и обратно. Numpy и pandas могут без проблем сделать это для вас с более быстрым временем выполнения. Использование dropped DataFrame:

import numpy as np

grouped = dropped.groupby('bank')['diff']

mean = grouped.apply(lambda x: np.mean(x))
std = grouped.apply(lambda x: np.std(x))

Ответ 4

Я бы предложил передать аргумент numeric_only=False в mean упомянутое Александром Усиковым - это работает для панд версии 0. 20+.

Если у вас более старая версия, работает следующее:

import pandas pd

df = pd.DataFrame({
    'td': pd.Series([pd.Timedelta(days=i) for i in range(5)]),
    'group': ['a', 'a', 'a', 'b', 'b']
})

(
    df
    .astype({'td': int})         # convert timedelta to integer (nanoseconds)
    .groupby('group')
    .mean()
    .astype({'td': 'timedelta64[ns]'})
)