如何使用Pandas对连续非空行的salary列取最大值、expense列取最小值
Pandas原生实现连续非空值聚合方案
核心逻辑通过isna()+cumsum()标记连续非空值分组,全程使用矢量化操作,性能远高于逐行遍历。
完整实现代码
import pandas as pd import numpy as np # 构造示例数据 df = pd.DataFrame({ 'Name': ['Ram', 'Ram', 'Ram', 'Ram', 'Ram'], 'date': [10, 12, 13, 14, 15], 'salary': [1000, 8000, np.nan, np.nan, 3000], 'expense': [np.nan, np.nan, 500, 800, np.nan] }) # 处理salary列:连续非空组取最大值,保留对应行 salary_group = df['salary'].isna().cumsum() salary_part = df.dropna(subset='salary') \ .groupby(salary_group) \ .apply(lambda x: x[x['salary'] == x['salary'].max()]) \ .reset_index(drop=True) # 处理expense列:连续非空组取最小值,保留对应行 expense_group = df['expense'].isna().cumsum() expense_part = df.dropna(subset='expense') \ .groupby(expense_group) \ .apply(lambda x: x[x['expense'] == x['expense'].min()]) \ .reset_index(drop=True) # 合并结果按日期排序 result = pd.concat([salary_part, expense_part]).sort_values('date').reset_index(drop=True) print(result)
输出结果
Name date salary expense 0 Ram 12 8000.0 NaN 1 Ram 13 NaN 500.0 2 Ram 15 3000.0 NaN
多主体适配说明
如果数据包含多个不同Name的用户,仅需将Name加入分组维度即可:
# 多Name场景下salary列处理示例 salary_part = df.dropna(subset='salary') \ .groupby(['Name', salary_group]) \ .apply(lambda x: x[x['salary'] == x['salary'].max()]) \ .reset_index(drop=True)
内容的提问来源于stack exchange,提问作者Pyd
相关产品推荐
相关产品推荐

