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

循环创建事件前后6个月的Pandas DataFrame并按规则命名

问题解决:动态生成事件前后6个月的DataFrame

场景与问题

现有一个包含约220万条记录的DataFrame dftxt,包含date(带时分的datetime类型)和text(字符串类型)两列。需要基于20个事件日期,为每个事件生成事件前6个月和事件后6个月的DataFrame,命名格式要求为preten1event1、postten1event1这类形式。

事件日期定义如下:

import datetime
from dateutil.relativedelta import relativedelta

ten1event1 = datetime.datetime(2011, 2, 15)
ten1event2 = datetime.datetime(2012, 9, 27)
ten1event3 = datetime.datetime(2013, 2, 10)
ten1event4 = datetime.datetime(2020, 3, 11)

ten2event1 = datetime.datetime(2013, 3, 25)
ten2event2 = datetime.datetime(2015, 10, 22)
ten2event3 = datetime.datetime(2018, 3, 7)
ten2event4 = datetime.datetime(2021, 9, 24)

ten3aevent1 = datetime.datetime(2010, 5, 22)
ten3aevent2 = datetime.datetime(2014, 1, 9)
ten3aevent3 = datetime.datetime(2020, 8, 11)
ten3aevent4 = datetime.datetime(2022, 1, 5)

ten3bevent1 = datetime.datetime(2013, 3, 25)
ten3bevent2 = datetime.datetime(2014, 7, 29)
ten3bevent3 = datetime.datetime(2017, 12, 1)
ten3bevent4 = datetime.datetime(2021, 10, 19)

ten4event1 = datetime.datetime(2011, 6, 14)
ten4event2 = datetime.datetime(2013, 7, 23)
ten4event3 = datetime.datetime(2014, 2, 11)
ten4event4 = datetime.datetime(2019, 2, 25)

原尝试代码如下,但运行后无法生成预期的DataFrame,报NameError: name 'preten1event1' is not defined:

events = [ten1event1,ten1event2,ten1event3,ten1event4,ten2event1,ten2event2,ten2event3,ten2event4,ten3aevent1,
          ten3aevent2,ten3aevent3,ten3aevent4,ten3bevent1,ten3bevent2,ten3bevent3,ten3bevent4,ten4event1,
          ten4event2,ten4event3,ten4event4]

for x in events:
    dfpre = dftxt.loc[(dftxt['date'] >= x - relativedelta(months=6)) & (dftxt['date'] <= x)]
    dfpre = dfpre.reset_index()
    dfpre.drop(columns=['index'], inplace=True)
    f"pre{x}" == dfpre
    
    dfpost = dftxt.loc[(dftxt['date'] >= x) & (dftxt['date'] <= x + relativedelta(months=6))]
    dfpost = dfpost.reset_index()
    dfpost.drop(columns=['index'], inplace=True)
    f"post{x}" == dfpost

错误原因

原代码中f"pre{x}" == dfpre只是执行字符串与DataFrame的比较操作,并没有将DataFrame赋值给对应名称的变量。同时,直接通过字符串无法直接创建变量,必须借助命名空间或容器来实现。

解决方案

方法1:动态创建全局变量(符合命名格式要求)

利用globals()字典(当前全局命名空间的映射),通过变量名字符串作为键,将DataFrame赋值到全局命名空间中。注意:需要把事件与其名称配对,才能生成对应的变量名。

修改后的代码:

# 重新定义事件列表,每个元素是(事件名称, 事件日期)的元组
events = [
    ('ten1event1', ten1event1),
    ('ten1event2', ten1event2),
    ('ten1event3', ten1event3),
    ('ten1event4', ten1event4),
    ('ten2event1', ten2event1),
    ('ten2event2', ten2event2),
    ('ten2event3', ten2event3),
    ('ten2event4', ten2event4),
    ('ten3aevent1', ten3aevent1),
    ('ten3aevent2', ten3aevent2),
    ('ten3aevent3', ten3aevent3),
    ('ten3aevent4', ten3aevent4),
    ('ten3bevent1', ten3bevent1),
    ('ten3bevent2', ten3bevent2),
    ('ten3bevent3', ten3bevent3),
    ('ten3bevent4', ten3bevent4),
    ('ten4event1', ten4event1),
    ('ten4event2', ten4event2),
    ('ten4event3', ten4event3),
    ('ten4event4', ten4event4),
]

for name, event_date in events:
    # 生成事件前6个月的DataFrame
    pre_df = dftxt.loc[
        (dftxt['date'] >= event_date - relativedelta(months=6)) & 
        (dftxt['date'] <= event_date)
    ].reset_index(drop=True)  # 简化索引重置操作
    globals()[f'pre{name}'] = pre_df
    
    # 生成事件后6个月的DataFrame
    post_df = dftxt.loc[
        (dftxt['date'] >= event_date) & 
        (dftxt['date'] <= event_date + relativedelta(months=6))
    ].reset_index(drop=True)
    globals()[f'post{name}'] = post_df

执行后即可直接使用preten1event1、postten1event1等变量。

方法2:用字典统一存储(更推荐)

不直接创建大量全局变量,而是用字典作为容器存储所有生成的DataFrame,避免污染全局命名空间,同时方便后续批量处理。

代码示例:

event_dfs = {}  # 存储所有事件前后的DataFrame

for name, event_date in events:
    # 事件前6个月数据
    pre_df = dftxt.loc[
        (dftxt['date'] >= event_date - relativedelta(months=6)) & 
        (dftxt['date'] <= event_date)
    ].reset_index(drop=True)
    event_dfs[f'pre{name}'] = pre_df
    
    # 事件后6个月数据
    post_df = dftxt.loc[
        (dftxt['date'] >= event_date) & 
        (dftxt['date'] <= event_date + relativedelta(months=6))
    ].reset_index(drop=True)
    event_dfs[f'post{name}'] = post_df

# 访问示例:获取ten1event1的前6个月数据
# event_dfs['preten1event1']

这种方式更易维护,后续遍历、修改所有事件数据时更便捷。

内容的提问来源于stack exchange,提问作者Jesse-Burton Nicholson

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.03 21:00:18