You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何用Numpy实现Pandas中类似的百分位排名计算?

用Numpy实现Pandas风格的百分位排名

要实现和df[rankCols].transform('rank', pct=True)完全一致的百分位排名,需要复刻Pandas的核心逻辑:对每列的重复值取平均排名,再将排名除以列的有效元素数(含NaN时仅统计非NaN元素)。以下是纯Numpy实现方案:

核心实现代码

import numpy as np

def numpy_pct_rank(arr):
    n_rows, n_cols = arr.shape
    
    def process_single_col(col):
        # 分离NaN和非NaN元素
        nan_mask = np.isnan(col)
        non_nan_col = col[~nan_mask]
        non_nan_count = len(non_nan_col)
        
        if non_nan_count == 0:
            return col  # 全NaN的列直接返回原数组
        
        # 对非NaN元素排序
        sorted_non_nan = np.sort(non_nan_col)
        # 找到每个元素在排序数组中的左右边界,用于计算平均排名
        left_pos = np.searchsorted(sorted_non_nan, non_nan_col, side='left')
        right_pos = np.searchsorted(sorted_non_nan, non_nan_col, side='right')
        
        # 计算平均排名(从1开始,和Pandas默认逻辑一致)
        avg_rank = (left_pos + right_pos - 1) / 2 + 1
        # 计算百分位排名
        pct_rank = avg_rank / non_nan_count
        
        # 构建最终列结果,保留NaN位置
        result_col = np.full_like(col, np.nan)
        result_col[~nan_mask] = pct_rank
        return result_col
    
    # 对每一列应用处理逻辑
    return np.apply_along_axis(process_single_col, axis=0, arr=arr)

使用示例

# 将目标列转为Numpy数组
arr = df[rankCols].values
# 计算百分位排名
pct_ranks = numpy_pct_rank(arr)

逻辑说明

  1. NaN处理:和Pandas默认行为一致,保留NaN且不参与排名计算,结果中NaN位置仍为NaN。
  2. 平均排名计算:通过np.searchsorted定位每个元素在排序数组中的首次、末次出现位置,取两者中间值作为平均排名(对应Pandas的method='average'规则,重复值取平均排名)。
  3. 百分位转换:将平均排名除以列的非NaN元素总数,得到0到1之间的百分位值,和Pandaspct=True的输出完全匹配。

验证一致性

可以通过以下代码确认结果和Pandas的一致性:

pandas_result = df[rankCols].transform('rank', pct=True).values
numpy_result = numpy_pct_rank(arr)
# 忽略浮点精度误差,检查结果是否一致
print(np.allclose(pandas_result, numpy_result, equal_nan=True))

内容的提问来源于stack exchange,提问作者user376285

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.12 10:07:06