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

如何将DataFrame中各分类的最近2个日期转换为指定字符串

解决Pandas按分类替换日期为“1st day”/“2nd day”的问题

问题背景

现有如下Pandas DataFrame:

category       date       value
0      A6TCE 2023-01-06         NaN
1      A6TCE 2023-01-09         NaN
2       BDTI 2023-01-06         NaN
3       BDTI 2023-01-09         NaN
4      S2TCE 2023-01-06         NaN
5      S2TCE 2023-01-09         NaN
6        TD1 2023-01-06       38.67
7        TD1 2023-01-09       37.39
8       TD14 2023-01-09      250.31
9       TD14 2023-01-10      248.31
10      TD15 2023-01-06       54.03
11      TD15 2023-01-09       52.36
12      TD18 2023-01-06      425.08
13      TD18 2023-01-09      417.08
14      TD19 2023-01-06      182.94
15      TD19 2023-01-09      201.38
16       TD2 2023-01-06       53.42
17       TD2 2023-01-09       51.59
18      TD20 2023-01-06       92.05
19      TD20 2023-01-09       93.95
20      TD21 2023-01-06      314.00
21      TD21 2023-01-09      301.00
22      TD22 2023-01-06  8437500.00
23      TD22 2023-01-09  8411111.00
24      TD23 2023-01-06       68.19
25      TD23 2023-01-09       67.38
26      TD25 2023-01-06      161.43
27      TD25 2023-01-09      151.43
28      TD26 2023-01-06      140.00
29      TD26 2023-01-09      137.81
30      TD3C 2023-01-06       52.91
31      TD3C 2023-01-09       50.77
32       TD6 2023-01-06      169.61
33       TD6 2023-01-09      168.67
34       TD7 2023-01-06      168.56
35       TD7 2023-01-09      168.25
36       TD8 2023-01-09      242.86
37       TD8 2023-01-10      241.79
38       TD9 2023-01-06      129.38
39       TD9 2023-01-09      128.44
40     V2TCE 2023-01-06         NaN
41     V2TCE 2023-01-09         NaN

需求是将每个分类下的较早日期替换为字符串“1st day”,最新日期替换为“2nd day”,处理后示例效果如下:

34       TD7 1st day      168.56
    35       TD7 2nd day      168.25
    36       TD8 1st day      242.86
    37       TD8 2nd day      241.79
    38       TD9 1st day      129.38
    39       TD9 2nd day      128.44

错误原因分析

用户最初尝试的代码是全局统一映射日期:

df_last_2d["date"] = df_last_2d["date"].dt.strftime("%Y-%m-%d")
days= dict(zip(sorted(df_last_2d["date"].unique()),["1st day","2nd day"]))
df_last_2d["date"] = df_last_2d["date"].apply(lambda x: days[x])

报错KeyError: '2023-01-10',原因是:全局的日期唯一值有3个(2023-01-06、2023-01-09、2023-01-10),但生成的days字典只映射了前两个,导致2023-01-10找不到对应值。本质问题是没有按分类单独处理日期顺序,而是试图全局统一替换,忽略了不同分类的日期组差异。

正确实现方法

方法一:分组后用分类编码映射

针对每个分类单独排序日期,再按顺序替换标签:

import pandas as pd

# 确保date列为datetime类型(如果原始数据是字符串的话)
df_last_2d['date'] = pd.to_datetime(df_last_2d['date'])

# 按category分组,对每组内的日期排序后生成编码,再映射为目标字符串
df_last_2d['date'] = df_last_2d.groupby('category')['date'].transform(
    lambda x: pd.Categorical(x, ordered=True).codes
).map({0: '1st day', 1: '2nd day'})

方法二:排序后用累积计数映射

先按分类和日期排序,给每组内的行分配序号,再替换标签:

import pandas as pd

df_last_2d['date'] = pd.to_datetime(df_last_2d['date'])
# 按分类分组,组内按日期升序排序
df_last_2d = df_last_2d.sort_values(['category', 'date'])
# 给每组内的行分配从0开始的序号
df_last_2d['day_label'] = df_last_2d.groupby('category').cumcount()
# 将序号映射为目标字符串
df_last_2d['date'] = df_last_2d['day_label'].map({0: '1st day', 1: '2nd day'})
# 可选:删除临时生成的day_label列
df_last_2d = df_last_2d.drop('day_label', axis=1)

两种方法的核心逻辑都是按分类独立处理日期顺序,确保每个分类下的较早日期对应“1st day”,较新日期对应“2nd day”,不受其他分类的日期影响。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.05 11:40:21