如何获取每行最后非空值在其所在列的分位数排名?
问题描述
现有如下DataFrame:
| index | Jan | Feb | Mar | Apr | May |
|---|---|---|---|---|---|
| A | 1 | 31 | 45 | 9 | 30 |
| B | 0 | 12 | |||
| C | 3 | 5 | 3 | 3 | |
| D | 2 | 2 | 3 | 16 | 14 |
| E | 0 | 0 | 56 |
需要实现:每行最后一个非空值在其所在列中进行分位数排名,例如A行的30和May列所有值对比,得到100%的排名。最终期望结果如下:
| Index | 每行最后值相对于其所在列的分位数 |
|---|---|
| A | 100% |
| B | 80% |
| C | 33.3% |
| D | 50% |
| E | 100% |
解决方案
通过以下步骤实现需求:
- 定位每行最后一个非空值的列名和对应数值
- 对每列计算各值的分位数排名(即该值在列中的相对占比)
- 匹配每行对应列的排名结果并格式化为百分比输出
具体代码实现:
import pandas as pd import numpy as np # 构建原始DataFrame df = pd.DataFrame({ 'Jan': [1, 0, 3, 2, 0], 'Feb': [31, 12, 5, 2, 0], 'Mar': [45, np.nan, 3, 3, 56], 'Apr': [9, np.nan, 3, 16, np.nan], 'May': [30, np.nan, np.nan, 14, np.nan] }, index=['A', 'B', 'C', 'D', 'E']) # 获取每行最后一个非空值的列名和对应值 last_col = df.apply(lambda x: x.last_valid_index(), axis=1) last_val = df.apply(lambda x: x.dropna().iloc[-1], axis=1) # 计算每列的分位数排名(pct=True返回0-1的比例值) col_ranks = df.rank(pct=True, axis=0) # 匹配结果并格式化为百分比 result = pd.DataFrame({ '每行最后值相对于其所在列的分位数': [ f"{col_ranks.loc[idx, col]*100:.1f}%" for idx, col in last_col.items() ] }, index=last_col.index) print(result)
代码说明
x.last_valid_index():遍历每行,获取最后一个非空值的列名df.rank(pct=True, axis=0):对每列计算各值的分位数排名,返回0到1之间的比例- 列表推导式匹配每行的列名与对应排名,格式化为带一位小数的百分比字符串
运行结果
每行最后值相对于其所在列的分位数 A 100.0% B 80.0% C 33.3% D 50.0% E 100.0%
内容的提问来源于stack exchange,提问作者lakadibo
相关产品推荐
相关产品推荐

