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

如何用更Pythonic且高效的方法基于日期序列给pandas DataFrame新增列?

基于日期区间快速给DataFrame批量赋值的优化方案

我需要根据另一数据集定义的日期序列,给pd.DataFrame新增一列。目前用循环实现了需求,但想找更Pythonic、运行更快的方法。

示例数据

import numpy as np
import pandas as pd

np.random.seed(2)

df1 = pd.DataFrame({
    "start": pd.date_range(start="1/1/2022", end="1/5/2022", freq="D"),
    "stop": pd.date_range(start="1/2/2022", end="1/6/2022", freq="D"),
    "seq_id": np.random.choice(["a", "b", "c"], size=5)
})

df2 = pd.DataFrame({
    "V1": np.random.randint(1, 10, 121),
    "seq_id": str()
}, index=pd.date_range(start="1/1/2022", end="1/6/2022", freq="H"))

当前解决方案(循环实现)

for i in range(len(df1)):
    df2.loc[df1.start[i]:df1.stop[i], "seq_id"] = df1.seq_id[i]

优化方案(向量化操作,高效简洁)

利用pandas的长格式转换、索引重排和前向填充,避免逐行循环:

# 将df1的start/stop转成长格式,标记每个区间的起始和结束节点
df1_melt = df1.melt(id_vars='seq_id', value_name='time', var_name='type')
# 处理结束节点:将stop时间延后1小时(匹配df2的小时粒度),并清空seq_id
df1_melt['seq_id'] = np.where(df1_melt['type'] == 'stop', '', df1_melt['seq_id'])
# 按时间排序并设置索引
df1_melt = df1_melt.sort_values('time').set_index('time')

# 重索引到包含df2所有时间点的索引,前向填充得到每个时间点对应的seq_id
df2['seq_id'] = df1_melt['seq_id'].reindex(df2.index.union(df1_melt.index)).ffill().loc[df2.index]

优势说明

  • 效率更高:避免了循环的逐行赋值,利用pandas的向量化操作,数据量越大性能提升越明显
  • 更Pythonic:用pandas原生的DataFrame操作替代手动循环,代码更简洁易读

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.09 01:10:27