如何按user_id分组求datetime64[ns]列的时间均值与value均值
问题:按用户分组计算时间部分均值与数值均值
数据结构与样本数据
DataFrame字段类型:
user_id: objectlocal time: datetime64[ns]value: int32
样本数据:
| user_id | local time | value | |
|---|---|---|---|
| 0 | user1 | 2023-01-01 00:00:00 | 3 |
| 1 | user1 | 2023-01-01 00:00:00 | 3 |
| 2 | user1 | 2023-01-01 01:00:00 | 7 |
| 3 | user1 | 2023-01-01 01:00:00 | 2 |
| 4 | user2 | 2023-01-01 02:00:00 | 4 |
| 5 | user2 | 2023-01-01 02:00:00 | 10 |
| 6 | user2 | 2023-01-01 03:00:00 | 7 |
| 7 | user2 | 2023-01-01 03:00:00 | 2 |
需求
- 按
user_id字段分组 - 计算
local time字段**仅时间部分(HH:MM:SS,不含日期)**的均值,以及value字段的均值
当前错误尝试
直接使用df.groupby('user_id').mean()无法得到正确结果,因为该方法会对datetime类型的local time计算包含日期的时间戳均值,而非仅时间部分的均值。
错误代码:
import pandas as pd import numpy as np # Set the random seed for reproducibility np.random.seed(123) # Define the number of users and values num_users = 2 num_values = 4 # Generate the user IDs user_ids = ['user{}'.format(i+1) for i in range(num_users)] # Generate the local time values local_time = pd.date_range(start='2023-01-01 00:00:00', periods=num_values, freq='H') # Generate the random values values = np.random.randint(1, 11, size=(num_values*num_users)) # Create the DataFrame df = pd.DataFrame({ 'user_id': np.repeat(user_ids, num_values), 'local time': np.repeat(local_time, num_users), 'value': values}) # 无法得到正确结果的计算方式 df.groupby('user_id').mean()
期望输出:
local time value user_id user1 00:30:00 3.75 user2 02:30:00 5.75
解决方案
核心思路:先将local time转换为当天的时间差(从00:00:00开始的时长),计算均值后再转换回HH:MM:SS格式。
完整代码:
import pandas as pd import numpy as np np.random.seed(123) num_users = 2 num_values = 4 user_ids = ['user{}'.format(i+1) for i in range(num_users)] local_time = pd.date_range(start='2023-01-01 00:00:00', periods=num_values, freq='H') values = np.random.randint(1, 11, size=(num_values*num_users)) df = pd.DataFrame({ 'user_id': np.repeat(user_ids, num_values), 'local time': np.repeat(local_time, num_users), 'value': values }) # 1. 剥离日期,得到当天的时间差(timedelta类型) df['time_delta'] = df['local time'] - df['local time'].dt.normalize() # 2. 分组计算时间差均值与value均值 result = df.groupby('user_id').agg( time_mean=('time_delta', lambda x: x.mean()), value_mean=('value', 'mean') ) # 3. 将时间差均值转换为HH:MM:SS格式 result['local time'] = result['time_mean'].dt.total_seconds().apply( lambda x: pd.to_datetime(x, unit='s').strftime('%H:%M:%S') ) # 4. 整理输出列顺序与名称 result = result[['local time', 'value_mean']].rename(columns={'value_mean': 'value'}) print(result)
执行后输出:
local time value user_id user1 00:30:00 3.75 user2 02:30:00 5.75
关键步骤说明
df['local time'].dt.normalize():将datetime转换为当天00:00:00的datetime对象,与原时间相减得到仅包含时间部分的timedelta。- 对timedelta求均值后,通过
dt.total_seconds()转换为总秒数,再格式化为HH:MM:SS字符串,得到仅时间部分的均值。
内容的提问来源于stack exchange,提问作者Leo
相关产品推荐
相关产品推荐

