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

按用户分组,基于d1列生成与d2列日期最接近的新列d3

问题描述

我有如下测试数据集:

import pandas as pd

df = pd.DataFrame({'user':[1,1,1,2,2,2,2,3,3,3,3,4,4,4,4,4],
                  'd1':['1995-09-01','1995-09-02','1995-10-03','1995-10-04','1995-10-05','1995-11-07','1995-11-08','1995-11-09','1995-11-10','1995-11-15','1995-12-18','1995-12-19','1995-12-20','1995-12-23','1995-12-26','1995-12-30'],
                  'd2':['1995-10-05','1995-10-05','1995-10-05',
                        '1995-11-08','1995-11-08','1995-11-08','1995-11-08',
                        '1995-12-10','1995-12-10','1995-12-10','1995-12-10',
                        '1995-12-27','1995-12-27','1995-12-27','1995-12-27','1995-12-27'],})

按user和d1排序(df = df.sort_values(['user', 'd1']))后结果如下:

user         d1         d2
    1  1995-09-01  1995-10-05
    1  1995-09-02  1995-10-05
    1  1995-10-03  1995-10-05
    2  1995-10-04  1995-11-08
    2  1995-10-05  1995-11-08
    2  1995-11-07  1995-11-08
    2  1995-11-08  1995-11-08
    3  1995-11-09  1995-12-10
    3  1995-11-10  1995-12-10
    3  1995-11-15  1995-12-10
    3  1995-12-18  1995-12-10
    4  1995-12-19  1995-12-27
    4  1995-12-20  1995-12-27
    4  1995-12-23  1995-12-27
    4  1995-12-26  1995-12-27
    4  1995-12-30  1995-12-27

需要生成新列d3,规则如下:

  • d3的值为当前user分组下,d1列中与d2列日期最接近的日期
  • 若d2的日期存在于该分组的d1中,则d3直接取该日期
  • 若不存在,则取该分组d1中最接近d2的日期

期望得到如下DataFrame:

user         d1         d2         d3
    1  1995-09-01  1995-10-05  1995-10-03
    1  1995-09-02  1995-10-05  1995-10-03
    1  1995-10-03  1995-10-05  1995-10-03
    2  1995-10-04  1995-11-08  1995-11-08
    2  1995-10-05  1995-11-08  1995-11-08
    2  1995-11-07  1995-11-08  1995-11-08
    2  1995-11-08  1995-11-08  1995-11-08
    3  1995-11-09  1995-12-10  1995-12-18
    3  1995-11-10  1995-12-10  1995-12-18
    3  1995-11-15  1995-12-10  1995-12-18
    3  1995-12-18  1995-12-10  1995-12-18
    4  1995-12-19  1995-12-27  1995-12-26
    4  1995-12-20  1995-12-27  1995-12-26
    4  1995-12-23  1995-12-27  1995-12-26
    4  1995-12-26  1995-12-27  1995-12-26
    4  1995-12-30  1995-12-27  1995-12-26

我参考过StackOverflow上的两个方案,但适配后未成功。


解决方案

步骤说明

  1. 将d1和d2转换为日期类型,确保日期计算准确
  2. 按user分组,对每个分组执行以下操作:
    • 获取当前分组的d1日期数组
    • 对分组内的d2日期,先检查是否存在于d1中,存在则直接取值;不存在则计算日期差绝对值,找到最接近的日期
  3. 将结果合并回原DataFrame得到d3列

代码实现

import pandas as pd
import numpy as np

# 1. 转换日期类型
df['d1'] = pd.to_datetime(df['d1'])
df['d2'] = pd.to_datetime(df['d2'])

# 2. 定义分组内找最接近日期的函数
def find_nearest_date(group):
    d1_dates = group['d1'].unique()
    d2_date = group['d2'].iloc[0]  # 同一分组内d2日期相同
    
    # 先检查d2是否在d1中
    if d2_date in d1_dates:
        nearest = d2_date
    else:
        # 计算日期差的绝对值,找到最小差值对应的日期
        diffs = np.abs(d1_dates - d2_date)
        nearest = d1_dates[np.argmin(diffs)]
    
    # 为分组内所有行赋值
    group['d3'] = nearest
    return group

# 3. 按user分组应用函数
df = df.groupby('user').apply(find_nearest_date)

# 4. 转换回字符串格式(可选,根据需求调整)
df['d1'] = df['d1'].dt.strftime('%Y-%m-%d')
df['d2'] = df['d2'].dt.strftime('%Y-%m-%d')
df['d3'] = df['d3'].dt.strftime('%Y-%m-%d')

# 查看结果
print(df)

代码解释

  • 日期转换:把字符串类型的日期转为datetime类型,才能进行日期差值的数学计算
  • 分组函数:同一用户的d2日期完全一致,所以只需取一次d2值计算,避免重复运算;优先检查d2是否在d1中,存在则直接返回,否则通过绝对值差找到最接近的日期
  • 格式转换:最后把日期转回字符串格式,和期望结果的格式保持统一

运行代码后即可得到符合要求的DataFrame。


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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.29 02:39:51