我有一个以名称和日期时间为列的数据集 名称的多个条目具有不同的日期时间
例如输入:
name datetime
------------------
A1 2018-07-20 17:04:20.486
A1 2018-07-18 17:48:30.910
A1 2018-07-18 19:13:05.636
A1 2018-07-17 15:01:30.976
A1 2018-07-17 18:21:13.113
B7 2018-07-18 16:38:33.410
B7 2018-07-18 17:30:46.893
B7 2018-07-17 15:45:48.673
B7 2018-07-18 03:01:41.826
B7 2018-07-19 18:12:40.923
C3 2018-07-18 19:07:41.973
C3 2018-07-17 16:59:51.646
C3 2018-07-18 19:41:41.280
C3 2018-07-20 16:01:44.543
C3 2018-07-20 16:01:22.860
我只需要弄清楚每个名字的平均时间/平均时间
示例输出:
name avg_time
B7 14:13:54
A1 17:29:44
C3 17:34:28
解决方案#1
我尝试用当前日期替换日期,然后执行 按名称分组,并获取平均时间
today = pd.datetime.today()
data['datetime'] = data['datetime'] .apply(lambda x: x.replace(day=today.day, month=today.month, year=today.year))
for name, group in data.groupby(by='name'):
avg_datetime(group['datetime'])
# avg_time calculation
def avg_datetime(series):
"""
takes a series of datetime and returns the avarage time in '%H:%M' format
:param series:
:return:
"""
series = pd.to_datetime(series)
dt_min = series.min()
deltas = [x - dt_min for x in series]
avg_datetime = dt_min + functools.reduce(operator.add, deltas) / len(deltas)
return avg_datetime.time().strftime('%H:%M')
解决方案2
我还尝试将时间转换为分钟总数,然后 计算平均值并改回格式
# convert to total minutes
dt_index = pd.DatetimeIndex(pd.to_datetime(data['datetime']).dt.strftime('%H:%M'))
data['total_mins'] = dt_index.hour * 60 + dt_index.minute
mean_mins_list = [[name, int(group['total_mins'].mean())]
for name, group in data.groupby(by='name', sort=False, as_index=False)]
avg_time_df = pd.DataFrame(mean_mins_list, columns=['name', 'avg_time'])
# revert to HH:MM format
avg_time_df['avg_time'] = avg_time_df['avg_time'].apply(lambda x: str(math.floor(x / 60)) + ':' + str(x % 60))
我的数据集非常庞大,大约有1000万个唯一名称,什么是执行此操作最快的方法
答案 0 :(得分:2)
这是一个选择。
计算从那天开始起每个datetime
的总秒数。然后对它们进行分组并计算平均值,因为它们在那时只是数字。最后,转换回datetime
,然后选择时间部分。
import pandas as pd
df['secs'] = (df.datetime - df.datetime.dt.normalize()).dt.total_seconds()
pd.to_datetime(df.groupby('name').secs.mean(), unit='s').dt.time
输出:
name
A1 17:29:44.224200
B7 14:13:54.345000
C3 17:34:28.460400
Name: secs, dtype: object