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

基于指定日期从Pandas列的分隔列表中筛选对应符号

问题描述

现有如下Pandas DataFrame,包含id、symbols和symbol_dates三列:

id symbols   symbol_dates
1  ABC       20070103:29991231
2  DEF;GH    20100307:20141215;20141216:29991231
3  IJ;KLM;NO 20040107:20051105;20051106:20180316;20180317:29991231
4  PQ        20080103:20090613
5  RST;UV    20080206:20150603;20150604:29991231
6  WXY       20070103:20130516

其中symbols与symbol_dates的内容均以分号分隔,每个符号对应一个日期区间(格式为YYYYMMDD:YYYYMMDD)。例如id=2时,日期区间20141216:29991231对应的符号是GH。

需求:输入一个日期(格式YYYYMMDD),返回新的DataFrame,仅保留该日期所属区间对应的符号;若输入日期不在该行的任何区间内,则丢弃该行。例如输入20141220时,预期输出:

id symbol
1 ABC
2 GH
3 KLM
5 RST
实现思路与方法

核心思路

  1. 统一日期格式:将输入日期和区间的起止日期转为整数,方便直接做大小比较
  2. 关联符号与区间:拆分每行的多符号、多区间为列表,保证符号和对应区间一一匹配
  3. 匹配筛选:找到每个id下包含输入日期的区间,取出对应符号;过滤无匹配的行

方法一:逐行遍历匹配

逻辑直观,适合理解基础匹配流程:

import pandas as pd

# 初始化示例DataFrame
df = pd.DataFrame({
    'id': [1,2,3,4,5,6],
    'symbols': ['ABC', 'DEF;GH', 'IJ;KLM;NO', 'PQ', 'RST;UV', 'WXY'],
    'symbol_dates': ['20070103:29991231', '20100307:20141215;20141216:29991231', 
                     '20040107:20051105;20051106:20180316;20180317:29991231',
                     '20080103:20090613', '20080206:20150603;20150604:29991231',
                     '20070103:20130516']
})

def filter_by_date(input_date):
    input_date_int = int(input_date)
    # 拆分每行的符号和区间为列表
    df['symbol_list'] = df['symbols'].str.split(';')
    df['date_range_list'] = df['symbol_dates'].str.split(';')
    
    # 定义函数,为每行找到匹配的符号
    def get_matching_symbol(row):
        for symbol, date_range in zip(row['symbol_list'], row['date_range_list']):
            start, end = map(int, date_range.split(':'))
            if start <= input_date_int <= end:
                return symbol
        return None  # 无匹配返回空
    
    # 应用函数生成匹配结果
    df['symbol'] = df.apply(get_matching_symbol, axis=1)
    # 过滤空结果,整理目标列
    result = df[df['symbol'].notna()][['id', 'symbol']].reset_index(drop=True)
    # 清理临时列
    df.drop(columns=['symbol_list', 'date_range_list'], inplace=True)
    return result

# 测试输入日期20141220
output = filter_by_date('20141220')
print(output)

方法二:用explode展开后筛选

利用Pandas的explode方法将多值字段拆分为多行,再做筛选,代码更简洁,大数据量下效率更高:

def filter_by_date_explode(input_date):
    input_date_int = int(input_date)
    # 拆分符号和区间,展开为每行对应一个符号-区间对
    expanded_df = df.assign(
        symbol=df['symbols'].str.split(';'),
        date_range=df['symbol_dates'].str.split(';')
    ).explode(['symbol', 'date_range'], ignore_index=True)
    
    # 拆分区间为起止日期并转为整数
    expanded_df[['start', 'end']] = expanded_df['date_range'].str.split(':', expand=True).astype(int)
    
    # 筛选输入日期在区间内的行,去重并整理列
    result = expanded_df[(expanded_df['start'] <= input_date_int) & (expanded_df['end'] >= input_date_int)][['id', 'symbol']]
    result = result.drop_duplicates(subset='id').reset_index(drop=True)
    return result

# 测试
output = filter_by_date_explode('20141220')
print(output)

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.26 00:24:31