使用Pandas筛选含A、B类别的ID并计算绝对小时时间差
解决方案
1. 数据准备(复现原始DataFrame)
import pandas as pd data = { 'ID': [1,1,1,2,3,3,3], 'Category': ['A','A','B','A','A','B','B'], 'Date': ['1/1/22 10:14:12 AM', '1/1/22 10:12:12 AM', '1/2/22 10:14:12 AM', '1/1/22 10:14:12 AM', '1/2/22 10:14:12 AM', '1/1/22 10:14:12 AM', '1/1/22 10:18:12 AM'] } df = pd.DataFrame(data)
2. 转换日期类型
将字符串格式的Date列转为datetime类型,支持后续时间运算:
df['Date'] = pd.to_datetime(df['Date'])
3. 筛选符合条件的ID
仅保留同时包含Category A和B的ID:
# 检查每个ID的Category集合是否包含A和B valid_ids = df.groupby('ID')['Category'].apply(lambda x: {'A', 'B'}.issubset(x.unique())) # 提取符合条件的ID列表 valid_ids = valid_ids[valid_ids].index.tolist() # 过滤原数据 filtered_df = df[df['ID'].isin(valid_ids)]
4. 聚合日期并计算时间差
对每个ID的A、B类日期取最小值(也可根据需求取最大值/平均值),再计算绝对时间差(小时为单位):
# 按ID和Category分组聚合日期,转宽表 aggregated = filtered_df.groupby(['ID', 'Category'])['Date'].min().unstack() # 计算时间差(秒转小时) aggregated['Time Difference'] = abs(aggregated['A'] - aggregated['B']).dt.total_seconds() / 3600 # 整理成目标格式 result = aggregated[['Time Difference']].reset_index().astype({'Time Difference': int})
最终结果
print(result)
输出:
ID Time Difference 0 1 24 1 3 24
补充说明
- 若同一ID+Category的多条记录需要其他聚合逻辑,只需将
min()替换为max()(取最晚日期)或mean()(取平均时间)即可,示例数据中结果一致。 - 时间差计算通过
dt.total_seconds()转换为秒后除以3600得到小时数,取绝对值确保结果为正。
内容的提问来源于stack exchange,提问作者CowboyCoder
相关产品推荐
相关产品推荐

