Python:如何在DataFrame中筛选用户单日最小Time值
解决方法:保留每个用户单日最小Time值的DataFrame
嘿,这个需求在日常处理pandas数据时太常见了,我给你两种实用的实现方式,都能精准达到你的要求——每个用户单日只保留一条最小Time的记录,而且新DataFrame的结构和原表完全一致。
先拿一个模拟的原DataFrame举例子,方便你对应理解:
import pandas as pd # 模拟原数据结构 df = pd.DataFrame({ 'UserID': ['A', 'A', 'B', 'B', 'B', 'C'], 'Date': ['2024-05-01', '2024-05-01', '2024-05-01', '2024-05-02', '2024-05-02', '2024-05-02'], 'Time': ['08:30', '09:15', '07:45', '10:00', '09:00', '11:20'], 'OtherInfo': ['签到', '打卡', '签到', '提交', '修改', '审核'] })
方法一:分组取最小时间的索引(精准定位)
这种方法适合需要明确获取每组最小值对应行的场景,步骤清晰:
- 先把
Time列转成可比较的时间类型(如果原数据是字符串格式的话,避免排序错误) - 按
UserID和Date分组,拿到每组中Time最小的行的索引 - 根据索引筛选出目标行,重置索引让结构更整洁
代码实现:
# 转换Time列类型(如果原数据不是时间类型的话) df['Time'] = pd.to_datetime(df['Time'], format='%H:%M').dt.time # 获取每组最小Time对应的行索引 min_time_indices = df.groupby(['UserID', 'Date'])['Time'].idxmin() # 筛选得到新DataFrame new_df = df.loc[min_time_indices].reset_index(drop=True)
方法二:排序后去重(直观易懂)
如果觉得分组索引有点绕,这种方法更直观,思路是先把数据按用户、日期、时间从小到大排好,然后去重时只留每组的第一条(也就是时间最小的那条):
代码实现:
# 同样先确保Time是可比较的类型(可选,若原字符串是HH:MM格式也能直接比较) df['Time'] = pd.to_datetime(df['Time'], format='%H:%M').dt.time # 按用户、日期、时间升序排序 sorted_df = df.sort_values(by=['UserID', 'Date', 'Time'], ascending=True) # 去重,保留每组(UserID+Date)的第一条记录 new_df = sorted_df.drop_duplicates(subset=['UserID', 'Date'], keep='first').reset_index(drop=True)
注意事项
- 如果你的
Time列已经是datetime.time类型,或者字符串格式是标准的HH:MM(比如09:00而非9:0),那转换类型的步骤可以省略,直接比较就行。 - 两种方法都会完整保留原DataFrame的所有列,不会丢失其他字段的数据,结构完全和原表一致。
内容的提问来源于stack exchange,提问作者VBalazs
相关产品推荐
相关产品推荐

