Поиск среднего и стандартного отклонения объекта 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))
Ответ 3
Панды mean()
и другие методы агрегации поддерживают параметр numeric_only=False
.
dropped.groupby('bank').mean(numeric_only=False)
Найдено здесь: Агрегации для значений Timedelta в Python DataFrame
Ответ 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]'})
)