如何基于duration列值生成符合填充规则的1分钟时间序列?
解决1分钟粒度时间序列按
duration填充连续时段的问题 你之前用df.resample("1min").fillna("pad")无效,是因为pad会把有效值一直填充到下一个数据点的前一刻,而非仅填充duration指定的连续分钟数。要实现仅在duration覆盖的时段填充值、其余时段留空NaN,可以按以下步骤操作:
核心思路
先将每一行数据按duration扩展为对应分钟数的行,再用完整的1分钟时间序列重新索引,缺失的时段自动填充NaN。
代码示例
1. 准备测试数据
import pandas as pd # 构造示例数据集 data = { 'datetime': ['2024-05-20 10:00:00', '2024-05-20 10:03:00'], 'action': ['login', 'process'], 'duration': [2, 3] # login覆盖10:00、10:01;process覆盖10:03、10:04、10:05 } df = pd.DataFrame(data) # 确保datetime为时间类型,且向下取整到分钟(处理原始数据带秒的情况) df['datetime'] = pd.to_datetime(df['datetime']).dt.floor('1min')
2. 扩展每行数据到对应分钟数
定义函数将单条记录扩展为duration个连续分钟的行:
def expand_row(row): # 生成当前操作覆盖的所有分钟点 time_points = pd.date_range( start=row['datetime'], periods=row['duration'], freq='1min' ) # 生成扩展后的行,重复action和duration值 return pd.DataFrame({ 'datetime': time_points, 'action': row['action'], 'duration': row['duration'] }) # 对所有行应用扩展函数并合并结果 expanded_df = pd.concat( [expand_row(row) for _, row in df.iterrows()], ignore_index=True )
3. 生成完整时间序列并补全NaN
先确定完整的时间范围,再重新索引得到目标结果:
# 计算完整时间范围:从最早操作时间到最晚操作结束时间 start_time = df['datetime'].min() end_time = df['datetime'].max() + pd.Timedelta(minutes=df['duration'].max() - 1) # 生成1分钟粒度的完整时间索引 full_time_index = pd.date_range(start=start_time, end=end_time, freq='1min') # 重新索引,缺失时段自动填充NaN result_df = expanded_df.set_index('datetime').reindex(full_time_index).reset_index() result_df.rename(columns={'index': 'datetime'}, inplace=True)
最终效果
运行后result_df的输出如下:
| datetime | action | duration |
|---|---|---|
| 2024-05-20 10:00:00 | login | 2 |
| 2024-05-20 10:01:00 | login | 2 |
| 2024-05-20 10:02:00 | NaN | NaN |
| 2024-05-20 10:03:00 | process | 3 |
| 2024-05-20 10:04:00 | process | 3 |
| 2024-05-20 10:05:00 | process | 3 |
额外细节处理
- 如果原始数据存在
duration=0的记录,可在expand_row函数中添加判断跳过,避免生成无效行。 - 若需将
duration改为记录单分钟时长(即每个填充行的duration为1),只需把扩展函数中的row['duration']替换为1即可。
内容的提问来源于stack exchange,提问作者prof32
相关产品推荐
相关产品推荐

