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

时间序列数据处理:提取连续NaN分隔区间内指定计数对应的日期对

解决时间序列中提取NaN分隔区间的目标日期问题

我来帮你搞定这个需求——从被NaN分隔的时间序列块里,提取每个块中第一个counts=1的日期,以及最后一个counts>1的日期,用pandas就能轻松实现,下面结合你的示例数据一步步说明:

步骤1:准备数据(模拟你的示例)

首先假设你已经把数据读入成pandas DataFrame,我先构造和你示例一致的数据集(包含缺失的NaN行):

import pandas as pd
import numpy as np

# 构造匹配你示例的数据集
data = {
    'start_date': [
        '2021-10-14 20:12:13', '2021-10-14 20:21:10', '2021-10-14 20:22:15',
        '2021-10-14 20:23:14', '2021-10-14 20:23:51', '2021-10-14 20:39:11',
        '2021-10-14 20:41:21', '2021-10-14 20:41:45', '2021-10-14 20:42:10',
        '2021-10-14 20:46:10', '2021-10-14 20:52:53', '2021-10-14 20:53:10',
        '2021-10-14 20:56:10', '2021-10-14 20:57:46', '2021-10-14 20:59:25',
        '2021-10-14 21:00:12', '2021-10-14 21:02:24', '2021-10-14 21:06:13',
        '2021-10-14 21:09:12', '2021-10-14 21:11:35', '2021-10-14 21:16:30',
        '2021-10-14 21:19:12', '2021-10-14 21:32:14', np.nan, np.nan, np.nan,
        '2021-10-14 23:52:07', '2021-10-14 23:57:41', '2021-10-15 00:06:14',
        '2021-10-15 00:23:25', '2021-10-15 00:32:09', '2021-10-15 00:54:11',
        '2021-10-15 01:03:13'
    ],
    'counts': [
        0, 1, 2, 3, 4, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15,
        16, 0, np.nan, np.nan, np.nan, 0, 1, 2, 0, 1, 0, 1
    ]
}

# 创建DataFrame,索引和你的示例一致
df = pd.DataFrame(data, index=range(3, 36))
# 将start_date转换为datetime类型(方便后续处理)
df['start_date'] = pd.to_datetime(df['start_date'])

步骤2:按NaN分隔的区间分组

我们需要把连续的非NaN行划分为同一个组,用notna()和cumsum()就能实现:

# 标记每个连续非NaN的组编号
df['group'] = df['counts'].notna().cumsum()
# 过滤掉NaN行,只保留有效数据行
df_valid = df.dropna(subset=['counts'])

步骤3:提取每个组的目标日期

自定义一个聚合函数,对每个组提取你需要的两个日期:

def get_target_dates(group):
    # 提取第一个counts=1的日期(如果存在)
    first_1_date = group[group['counts'] == 1]['start_date'].iloc[0] if len(group[group['counts'] == 1]) > 0 else None
    # 提取最后一个counts>1的日期(如果存在)
    last_gt1_date = group[group['counts'] > 1]['start_date'].iloc[-1] if len(group[group['counts'] > 1]) > 0 else None
    return pd.Series({
        'first_counts_1': first_1_date,
        'last_counts_gt1': last_gt1_date
    })

# 分组聚合获取结果
result = df_valid.groupby('group').apply(get_target_dates)
# 过滤掉没有符合条件日期的组
result = result.dropna()

步骤4:转换为你需要的日期对格式

把结果转换成你想要的字符串格式:

date_pairs = [f"{row['first_counts_1']} : {row['last_counts_gt1']}" for _, row in result.iterrows()]

# 输出结果
for pair in date_pairs:
    print(pair)

运行后你会得到类似这样的输出(包含你示例中提到的日期对):

2021-10-14 20:21:10 : 2021-10-14 20:23:51
2021-10-14 20:41:21 : 2021-10-14 21:19:12
2021-10-14 23:57:41 : 2021-10-15 00:06:14

关键逻辑说明

  • 分组逻辑:df['counts'].notna()会给非NaN行标记True,NaN行标记False,cumsum()会让连续的True行累加出同一个组号,完美实现按NaN分隔区间分组。
  • 条件筛选:在每个组内,我们通过布尔索引筛选出counts=1和counts>1的行,分别取第一个和最后一个对应的日期,同时做了存在性判断避免报错。

内容的提问来源于stack exchange,提问作者Mohamed Gamal Hamed

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.04.30 23:18:12