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

如何高效获取Pandas DataFrame指定日期前的最新状态及统计数量

高效获取Pandas每行指定日期前的最新状态

问题背景

给定截止日期2020-05-31,以及如下列名为状态的Pandas DataFrame(值为日期或None):

rejected revocation    decision         rfe   interview premium    received rfe_response  biometrics withdrawal appeal
196      None       None  2020-01-28        None        None    None  2020-01-16         None        None       None   None
203      None       None  2020-06-20  2020-04-01        None    None  2020-01-03   2020-08-08        None       None   None
209      None       None  2020-12-03  2020-06-03        None    None  2020-01-03         None        None       None   None
213      None       None  2020-06-23        None        None    None  2020-01-27         None  2020-02-19       None   None
1449     None       None  2020-05-12        None        None    None  2020-01-06         None        None       None   None
1660     None       None  2021-09-23  2021-05-27        None    None  2020-01-21   2021-08-17        None       None   None

需求为:

  1. 获取每行中在截止日期及之前的最新状态(形式一:索引对应状态)
  2. 统计各状态的出现数量(形式二:包含所有状态,数量为0的需显示)

当前逐行循环构建字典排序的方法速度极慢,需要更高效的实现方式。

高效实现方案

利用Pandas的矢量化操作替代循环,充分发挥其底层优化优势:

步骤1:数据预处理

import pandas as pd

# 定义截止日期
cutoff_date = pd.to_datetime('2020-05-31')

# 构建示例DataFrame(已有DataFrame可跳过此步)
data = {
    'rejected': [None, None, None, None, None, None],
    'revocation': [None, None, None, None, None, None],
    'decision': ['2020-01-28', '2020-06-20', '2020-12-03', '2020-06-23', '2020-05-12', '2021-09-23'],
    'rfe': [None, '2020-04-01', '2020-06-03', None, None, '2021-05-27'],
    'interview': [None, None, None, None, None, None],
    'premium': [None, None, None, None, None, None],
    'received': ['2020-01-16', '2020-01-03', '2020-01-03', '2020-01-27', '2020-01-06', '2020-01-21'],
    'rfe_response': [None, '2020-08-08', None, None, None, '2021-08-17'],
    'biometrics': [None, None, None, '2020-02-19', None, None],
    'withdrawal': [None, None, None, None, None, None],
    'appeal': [None, None, None, None, None, None]
}
df = pd.DataFrame(data, index=[196, 203, 209, 213, 1449, 1660])

# 将所有列转换为datetime类型,None自动转为NaT(缺失时间值)
df = df.apply(pd.to_datetime, errors='coerce')

步骤2:筛选截止日期前的有效日期

# 仅保留截止日期及之前的日期,之后的日期设为NaT
df_filtered = df.where(df <= cutoff_date)

步骤3:获取每行最新状态

# 按行取最大日期对应的列名,即为该行最新状态
latest_status = df_filtered.idxmax(axis=1)

输出形式一:索引对应最新状态

for idx, status in latest_status.items():
    print(f"{idx}: {status}")

输出结果:

196: decision
203: rfe
209: received
213: biometrics
1449: decision
1660: received

输出形式二:状态数量统计

# 统计各状态数量,确保包含原DataFrame的所有列(数量为0的填充为0)
status_counts = latest_status.value_counts().reindex(df.columns, fill_value=0)

# 按指定格式输出
print("{")
for col, count in status_counts.items():
    print(f"{col} = {count},")
print("}")

输出结果:

{
rejected = 0,
revocation = 0,
decision = 2,
rfe = 1,
interview = 0,
premium = 0,
received = 2,
rfe_response = 0,
biometrics = 1,
withdrawal = 0,
appeal = 0,
}

注:原需求示例形式二中biometrics标注为0是错误值,实际213行的biometrics日期在截止日期范围内,统计应为1。

方案优势

全程使用Pandas矢量化操作,避免逐行循环,相比原方法速度提升显著,尤其在数据量较大时效果更明显。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.20 13:48:22