如何在Pandas中根据日期最小值获取对应列名与列值?
实现日期最小值对应的配对列信息提取
数据集与预处理代码
首先是原始数据集及已完成的日期转换和最小值计算:
import pandas as pd import numpy as np # 原始数据集 df = pd.DataFrame({'ID': [1, 1, 1, 1, 1, 1, 1, 1, 1, 2, 2, 2, 2, 2, 2], 'DATE_11': ['1/1/2011','1/2/2015', '1/3/2015','1/4/2012','1/5/2011','1/6/2011','1/7/2011','1/8/2009', '1/9/2016','1/2/2015','1/3/2015','1/4/2015','1/5/2015','1/6/1998','1/7/2011'], 'Column_1': ['A','B','S','A','B','S','A','A','C','A','A','A','A','A','A'], 'DATE_22': ['1/1/2015','1/2/2013', '1/3/2012','1/4/2015','1/5/2015','1/6/2015','1/7/2015','1/8/2015', '1/9/2016','1/2/2015','1/3/2015','1/4/2015','1/5/2015',np.nan,'1/7/2011'], 'Column_2': ['A','A','A','A','B','B','A','A','B','S','A','A','A','A','A'], 'DATE_3': ['1/1/2016','1/2/2015', '1/3/2015','1/4/2015','1/5/2015','1/6/2015','1/7/2015','1/8/2015', '1/1/2016','1/2/2011','1/3/2001','1/4/2002','1/5/2006','1/6/1998','1/7/2011'], 'Column_S': ['A','A','B','S','B','B','A','B','S','A','A','E','D','A','C']}) # 已完成的预处理:日期格式转换与最小值计算 df[['DATE_11','DATE_22','DATE_3']] = df[['DATE_11','DATE_22','DATE_3']].apply(pd.to_datetime, format='%m/%d/%Y') df['min_result'] = df[['DATE_11','DATE_22','DATE_3']].min(axis = 1)
需求说明
需要实现:
- 定位
min_result对应的原始日期列(DATE_11/DATE_22/DATE_3),并提取其配对的列名(Column_1/Column_2/Column_S)及对应值 - 以下场景下,配对列名和值设为
np.nan:- 多个非null日期列的值等于最小值(包括所有日期值相同的情况)
- 两个日期值相同且其中一个为null
实现方案
步骤1:定义日期列与配对列的映射
先建立日期列和对应数据列的关联关系:
date_to_col = { 'DATE_11': 'Column_1', 'DATE_22': 'Column_2', 'DATE_3': 'Column_S' }
步骤2:标记并统计最小值出现的次数
生成布尔矩阵标记每行中等于最小值的日期列,再统计有效(非null)的最小值列数量:
# 生成布尔矩阵:每个日期列是否等于该行的min_result is_min = df[['DATE_11', 'DATE_22', 'DATE_3']].eq(df['min_result'], axis=0) # 统计每行中等于最小值的非null列数量 min_col_count = is_min.sum(axis=1)
步骤3:提取配对列信息并处理特殊场景
先获取对应配对列的名称和值,再对需要设为np.nan的场景进行覆盖:
# 获取每行中第一个等于最小值的日期列 first_min_col = is_min.idxmax(axis=1) # 映射到对应的配对列名 df['matched_col_name'] = first_min_col.map(date_to_col) # 提取配对列的对应值 df['matched_col_value'] = df.apply(lambda row: row[row['matched_col_name']], axis=1) # 处理特殊场景:最小值出现多次,或所有日期均为null special_mask = (min_col_count >= 2) | df['min_result'].isna() df.loc[special_mask, ['matched_col_name', 'matched_col_value']] = np.nan
验证结果
查看最终结果的关键列:
print(df[['ID', 'min_result', 'matched_col_name', 'matched_col_value']])
输出示例(部分行):
ID min_result matched_col_name matched_col_value 0 1 2011-01-01 Column_1 A 1 1 2013-02-01 Column_2 A 2 1 2012-03-01 Column_2 A ... 13 2 1998-06-01 NaN NaN 14 2 2011-07-01 NaN NaN
内容的提问来源于stack exchange,提问作者Sam
相关产品推荐
相关产品推荐

