如何用Pandas筛选5分钟区间内各测量类型的最晚时间数据?
问题:按5分钟向上取整区间筛选各测量类型的最晚测量值
需求说明
需要为每种测量类型,筛选出5分钟时间区间内最晚时间对应的测量值,时间规则:
- 向上取整至所属的5分钟区间
- 当时间等于区间边界时归为当前区间(例如:
2017-01-03 10:05:00属于10:05:00区间而非10:10:00)
示例数据与初始化代码
import pandas as pd data = [ ["2017-01-03T10:04:45", "A", "35.79"], ["2017-01-03T10:01:18", "B", "98.78"], ["2017-01-03T10:09:07", "A", "35.01"], ["2017-01-03T10:03:34", "B", "96.49"], ["2017-01-03T10:02:01", "A", "35.82"], ["2017-01-03T10:05:00", "B", "97.17"], ["2017-01-03T10:05:01", "B", "95.08"] ] df = pd.DataFrame(data, columns=["timestamp", "measurement_type", "measurement_value"]) df['timestamp'] = pd.to_datetime(df['timestamp']) df['measurement_value'] = df['measurement_value'].astype(float)
初始DataFrame:
| timestamp | measurement_type | measurement_value |
|---|---|---|
| 2017-01-03 10:04:45 | A | 35.79 |
| 2017-01-03 10:01:18 | B | 98.78 |
| 2017-01-03 10:09:07 | A | 35.01 |
| 2017-01-03 10:03:34 | B | 96.49 |
| 2017-01-03 10:02:01 | A | 35.82 |
| 2017-01-03 10:05:00 | B | 97.17 |
| 2017-01-03 10:05:01 | B | 95.08 |
期望输出
| timestamp | measurement_type | measurement_value |
|---|---|---|
| 2017-01-03 10:05:00 | A | 35.79 |
| 2017-01-03 10:10:00 | A | 35.01 |
| 2017-01-03 10:05:00 | B | 97.17 |
| 2017-01-03 10:10:00 | B | 95.08 |
尝试的代码及问题
尝试代码:
df.groupby(["measurement_type", pd.Grouper(key="timestamp", freq="5min", offset="1sec")])["timestamp"].max()
遇到的问题:
- 时间是向下取整而非向上取整(临时方案是给每个时间加5分钟,需更优解)
- 使用
offset="1sec"后时间带有01秒,不符合格式要求 - 输出为Series,丢失
measurement_value列,无法得到与期望格式一致的DataFrame
解决方案
完整代码
import pandas as pd # 初始化数据 data = [["2017-01-03T10:04:45", "A", "35.79"],["2017-01-03T10:01:18", "B", "98.78"],["2017-01-03T10:09:07", "A", "35.01"],["2017-01-03T10:03:34", "B", "96.49"],["2017-01-03T10:02:01", "A", "35.82"],["2017-01-03T10:05:00", "B", "97.17"],["2017-01-03T10:05:01", "B", "95.08"]] df = pd.DataFrame(data, columns=["timestamp", "measurement_type", "measurement_value"]) df['timestamp'] = pd.to_datetime(df['timestamp']) df['measurement_value'] = df['measurement_value'].astype(float) # 1. 计算每个时间对应的5分钟区间上限(满足向上取整且边界归当前区间) df['interval'] = df['timestamp'].dt.ceil('5min') # 2. 按测量类型和区间分组,筛选每组中时间最晚的行 result = df.sort_values('timestamp').groupby(['measurement_type', 'interval'], as_index=False).last() # 3. 调整列名和顺序,匹配期望输出 result = result.rename(columns={'interval': 'timestamp'}).reindex(columns=['timestamp', 'measurement_type', 'measurement_value']) print(result)
代码解释
- 区间计算:使用
dt.ceil('5min')实现向上取整,完美符合需求:10:04:45→10:05:0010:05:00→10:05:00(边界归当前区间)10:05:01→10:10:00
- 分组筛选最晚值:先按
timestamp排序,再用groupby(...).last()直接获取每组最后一行(即时间最晚的记录),自动保留measurement_value列 - 格式调整:将
interval列重命名为timestamp,并调整列顺序与期望输出一致
运行结果
timestamp measurement_type measurement_value 0 2017-01-03 10:05:00 A 35.79 1 2017-01-03 10:10:00 A 35.01 2 2017-01-03 10:05:00 B 97.17 3 2017-01-03 10:10:00 B 95.08
内容的提问来源于stack exchange,提问作者Samat
相关产品推荐
相关产品推荐

