基于年月对比Pandas两列值的首次出现顺序问题
问题
现有一份已按年份、月份排序的Pandas DataFrame,结构如下:
Account year month value_1 value_2 A 2021 Jan 9 A 2021 Feb A 2021 Mar 7 A 2021 Apr 8 A 2021 May B 2021 Jan 2 B 2021 Feb 10 B 2021 Mar 5 B 2021 Apr 7
需要按账户分组,判断value_1和value_2的非空值哪个首次出现更早,生成如下结果DataFrame:
account result A value_2 appeared before value_1 B value_1 appeared before value_2
请问如何实现该需求?
解决方案
可以通过分组提取首次非空值位置、对比时间顺序的方式实现,具体步骤和代码如下:
完整实现代码
import pandas as pd # 构造示例数据(原数据空值用pd.NA表示) data = { 'Account': ['A', 'A', 'A', 'A', 'A', 'B', 'B', 'B', 'B'], 'year': [2021]*9, 'month': ['Jan', 'Feb', 'Mar', 'Apr', 'May', 'Jan', 'Feb', 'Mar', 'Apr'], 'value_1': [pd.NA, pd.NA, 7, 8, pd.NA, 2, pd.NA, 5, 7], 'value_2': [9, pd.NA, pd.NA, pd.NA, pd.NA, pd.NA, 10, pd.NA, pd.NA] } df = pd.DataFrame(data) # 定义分组处理逻辑 def compare_first_non_null(group): # 获取value_1首次非空的行索引(全为空则设为无穷大) idx1 = group[group['value_1'].notna()].index.min() if not group['value_1'].isna().all() else float('inf') # 获取value_2首次非空的行索引(全为空则设为无穷大) idx2 = group[group['value_2'].notna()].index.min() if not group['value_2'].isna().all() else float('inf') if idx2 < idx1: return 'value_2 appeared before value_1' elif idx1 < idx2: return 'value_1 appeared before value_2' else: return 'Both have no non-null values or appeared at the same time' # 分组计算并整理结果格式 result_df = df.groupby('Account').apply(compare_first_non_null).reset_index(name='result') result_df.rename(columns={'Account': 'account'}, inplace=True) print(result_df)
关键逻辑说明
- 空值处理:用
pd.NA统一表示原数据中的空值,符合Pandas的空值判断规范 - 首次非空位置提取:利用原DataFrame已按年月排序的特性,通过
index.min()获取首次出现非空值的行索引(索引越小代表时间越早) - 对比逻辑:用
float('inf')处理某列全为空的场景,确保比较逻辑不会出错 - 结果整理:将分组计算的结果重置索引、重命名列,最终得到需求格式的DataFrame
内容的提问来源于stack exchange,提问作者Django0602
相关产品推荐
相关产品推荐

