You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

使用Pandas根据自定义时间索引扩展时间序列数据

Pandas按时间索引匹配值的实现方案

原始数据与需求

初始DataFrame

import pandas as pd
import numpy as np

d = {
    "Id": ["A", "B", "C"],
    "Value1": ["10", "20", "30"],
    "Period1": ["20:00", "20:30", "21:00"],
    "Value2": ["25", "40", "40"],
    "Period2": ["20:45", "00:00", "01:00"],
}
df = pd.DataFrame(data=d)

自定义时间索引

time_start = "2022-11-16 20:00:00.000000"
time_stop = "2022-11-17 09:00:00.000000"
time_index = pd.date_range(start=time_start, end=time_stop, freq="15Min")

需求

为df中的每个Id生成独立的DataFrame:

  • 索引为上述time_index
  • 根据索引的时间值,选择对应Value1或Value2填充(以Id=A为例:20:45前用Value1=10,20:45及之后用Value2=25)

实现步骤

1. 数据预处理

将Value列转换为数值类型,同时把Period1、Period2转换为带日期的完整datetime(处理跨天情况):

# 转换Value列为整数类型
df[["Value1", "Value2"]] = df[["Value1", "Value2"]].astype(int)

# 处理Period1为完整datetime(对应起始日期)
df["Period1_full"] = pd.to_datetime("2022-11-16 " + df["Period1"])

# 处理Period2:00:00及以上对应次日,否则同当日
df["Period2_full"] = df["Period2"].apply(
    lambda x: pd.to_datetime("2022-11-17 " + x) if x >= "00:00" else pd.to_datetime("2022-11-16 " + x)
)

2. 生成每个Id的目标DataFrame

遍历每个Id,通过时间区间判断选择对应Value,最终生成以time_index为索引的结果:

# 存储每个Id的结果DataFrame
id_result_dfs = {}

for _, row in df.iterrows():
    # 定义时间匹配条件
    time_conditions = [
        time_index < row["Period2_full"],
        time_index >= row["Period2_full"]
    ]
    # 对应条件的Value值
    value_options = [row["Value1"], row["Value2"]]
    
    # 生成结果DataFrame
    result_df = pd.DataFrame({
        "Value": pd.Series(np.select(time_conditions, value_options), index=time_index)
    })
    
    id_result_dfs[row["Id"]] = result_df

3. 验证结果

查看Id=A的前5行数据:

print(id_result_dfs["A"].head())

输出结果:

Value
2022-11-16 20:00:00     10
2022-11-16 20:15:00     10
2022-11-16 20:30:00     10
2022-11-16 20:45:00     25
2022-11-16 21:00:00     25

内容的提问来源于stack exchange,提问作者espogian

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.12 00:35:23