Pandas如何获取行最大值且仅高于历史非空值时返回值和对应列名
实现代码
import io, pandas as pd, numpy as np # 生成测试数据(可替换为你的实际数据) t = io.StringIO(""" datetime|1|2|3 2021-01-23 00:00:00| 20|NaN| 15 2021-01-23 00:01:00| 12|NaN|NaN 2021-01-23 00:02:00| 10| 17|NaN 2021-01-23 00:03:00|NaN| 14| 18 2021-01-23 00:04:00| 16| 12|NaN""") df = pd.read_csv(t, sep='|', parse_dates=['datetime'], dtype=np.float64).set_index('datetime') # 核心计算逻辑 # 1. 生成前向填充的副本,仅用于比较,不修改原始数据 df_ffill = df.ffill() # 2. 分别计算原始数据每行最大值、填充后数据每行最大值 row_max_original = df.max(axis=1) row_max_ffill = df_ffill.max(axis=1) # 3. 筛选符合条件的new_max:仅当当前行原始最大值等于全局最大值(含历史值)时保留,否则为NaN df['new_max'] = np.where(row_max_original == row_max_ffill, row_max_original, np.nan) # 4. 匹配new_max对应的列名 df['new_max_col'] = df.apply( lambda x: x[x == x['new_max']].index[0] if pd.notna(x['new_max']) else np.nan, axis=1 ) print(df)
逻辑说明
核心思路是把「用于比较的历史填充值」和「实际需要写入的当前值」分开处理:
- 前向填充得到的副本只做最大值比较用,不会被写入结果
- 当原始数据当前行的最大值和填充后全局最大值相等时,说明当前行的最大值已经超过所有列的历史有效值,符合写入规则;如果填充后的最大值更大,说明全局最大值来自历史填充值,不属于当前行的新有效值,因此返回NaN
- 方案支持任意数量的数值列,也兼容任意长度的连续NaN场景
输出结果
1 2 3 new_max new_max_col datetime 2021-01-23 00:00:00 20.0 NaN 15.0 20.0 1 2021-01-23 00:01:00 12.0 NaN NaN NaN NaN 2021-01-23 00:02:00 10.0 17.0 NaN 17.0 2 2021-01-23 00:03:00 NaN 14.0 18.0 18.0 3 2021-01-23 00:04:00 16.0 12.0 NaN NaN NaN
内容的提问来源于stack exchange,提问作者Mike
相关产品推荐
相关产品推荐

