Pandas:基于df2的分类时间戳范围过滤df1的时间戳
Pandas按分类时间范围过滤DataFrame记录
需求说明
现有两个Pandas DataFrame:
- df1包含
Parent_Cat(父分类)、Child_Cat(子分类)、TimeStamp(时间戳)列 - df2包含
Parent_Cat、Child_Cat、Tmin(最小时间戳)、Tmax(最大时间戳)列,其中Tmin和Tmax为每个父子分类对应的时间戳范围边界
需要对df1进行过滤,仅保留每个父子分类中TimeStamp处于df2对应Tmin与Tmax之间(包含边界)的记录。
示例数据
import pandas as pd data_df1 = [[2, 9, "2023-01-10 15:03:24.100"], [2, 9, "2023-01-10 15:03:30.500"], [2, 9, "2023-01-10 15:05:20.300"], [2, 9, "2023-01-10 15:05:59.600"], [2, 10, "2023-01-10 15:03:24.100"], [2, 10, "2023-01-10 15:03:30.500"], [2, 11, "2023-01-10 15:03:40.300"], [2, 11, "2023-01-10 15:04:42.600"], [2, 11, "2023-01-10 15:05:54.600"], [3, 9, "2023-01-10 15:05:54.100"], [3, 9, "2023-01-10 15:06:30.500"], [3, 9, "2023-01-10 15:07:20.300"], [3, 9, "2023-01-10 15:08:59.600"], [3, 10, "2023-01-10 15:05:55.200"], [3, 10, "2023-01-10 15:06:01.500"], [3, 10, "2023-01-10 15:06:10.300"], [3, 11, "2023-01-10 15:05:59.600"], [3, 11, "2023-01-10 15:06:05.600"], [3, 11, "2023-01-10 15:06:06.900"]] data_df2 = [[2, 9, "2023-01-10 15:03:25.600", "2023-01-10 15:05:53.600"], [2, 10, "2023-01-10 15:03:24.200", "2023-01-10 15:03:34.500"], [2, 11, "2023-01-10 15:03:41.900", "2023-01-10 15:05:53.900"], [3, 9, "2023-01-10 15:05:55.400", "2023-01-10 15:08:23.200"], [3, 10, "2023-01-10 15:05:55.200", "2023-01-10 15:06:03.100"], [3, 11, "2023-01-10 15:05:56.000", "2023-01-10 15:06:06.000"]] df1 = pd.DataFrame(data_df1, columns=['Parent_Cat', 'Child_Cat', 'TimeStamp']) df2 = pd.DataFrame(data_df2, columns=['Parent_Cat', 'Child_Cat', 'Tmin', 'Tmax'])
按需求过滤后,df1应保留行索引为1、2、5、7、10、11、13、14、16、17的记录。
解决方案
步骤说明
- 转换时间列类型:将所有时间相关列(
TimeStamp、Tmin、Tmax)转换为Pandas的datetime类型,确保可以进行时间比较。 - 合并DataFrame:通过
Parent_Cat和Child_Cat将df1与df2合并,让df1每条记录都带上对应分类的时间范围边界。 - 过滤符合条件的记录:筛选出
TimeStamp在Tmin和Tmax之间(包含边界)的行。 - 清理冗余列(可选):如果不需要保留
Tmin和Tmax列,可以删除。
完整代码
# 转换时间列为datetime类型 df1['TimeStamp'] = pd.to_datetime(df1['TimeStamp']) df2['Tmin'] = pd.to_datetime(df2['Tmin']) df2['Tmax'] = pd.to_datetime(df2['Tmax']) # 合并df1和df2,关联对应分类的时间范围 merged_df = df1.merge(df2, on=['Parent_Cat', 'Child_Cat'], how='left') # 过滤符合时间范围的记录 filtered_df = merged_df[(merged_df['TimeStamp'] >= merged_df['Tmin']) & (merged_df['TimeStamp'] <= merged_df['Tmax'])] # 可选:删除Tmin和Tmax列,恢复原df1的结构 filtered_df = filtered_df.drop(columns=['Tmin', 'Tmax']) # 验证结果:查看保留的行索引 print(filtered_df.index.tolist()) # 输出:[1, 2, 5, 7, 10, 11, 13, 14, 16, 17]
代码说明
- 使用
pd.to_datetime()转换时间列是关键,字符串格式的时间无法直接进行大小比较。 merge()方法通过共同的分类列关联两个DataFrame,确保每条记录都能匹配到对应的时间范围。- 布尔条件
(merged_df['TimeStamp'] >= merged_df['Tmin']) & (merged_df['TimeStamp'] <= merged_df['Tmax'])精准筛选出符合时间区间的记录。
内容的提问来源于stack exchange,提问作者Pramesh Pudasaini
相关产品推荐
相关产品推荐

