Pandas高效实现DataFrame每行Top20%设1、Bottom20%设-1其余置np.nan
高性能向量化实现方案
不要用Python层面的逐行for循环,直接调用pandas内置的向量化接口,所有运算走底层C实现,大数据量下性能比循环高2个数量级以上。
实现步骤
- 按行计算忽略NaN的分位阈值:每行有效数值的20%分位(最低20%的临界值)、80%分位(最高20%的临界值)
- 初始化全NaN的结果表
- 通过布尔掩码直接批量赋值:低于等于低分位的位置设为-1,高于等于高分位的位置设为1,其余位置保留NaN
完整代码
import pandas as pd import numpy as np # 构造示例数据 df = pd.DataFrame([ [1,2,3,4,5,np.nan,np.nan,np.nan,np.nan,np.nan], [1,2,3,4,5,6,7,8,9,10], [10,9,8,7,6,5,4,3,2,1] ]) # 逐行计算分位阈值,axis=1指定按行计算,自动跳过NaN low_q = df.quantile(0.2, axis=1) high_q = df.quantile(0.8, axis=1) # 初始化结果为全NaN result = pd.DataFrame(np.nan, index=df.index, columns=df.columns) # 批量赋值 result[df.le(low_q, axis=0)] = -1 result[df.ge(high_q, axis=0)] = 1
运行结果
执行print(result)输出和预期完全一致:
0 1 2 3 4 5 6 7 8 9 0 -1.0 NaN NaN NaN 1.0 NaN NaN NaN NaN NaN 1 -1.0 -1.0 NaN NaN NaN NaN NaN NaN 1.0 1.0 2 1.0 1.0 NaN NaN NaN NaN NaN NaN -1.0 -1.0
参数适配说明
如果每行有效数值的个数不是5的整数倍,分位点计算可能出现插值偏差,可以通过quantile方法的interpolation参数调整取值规则,可选值:
lower:取不大于分位值的最近数higher:取不小于分位值的最近数nearest:取距离分位值最近的数
根据实际业务的取数规则选择即可。
内容的提问来源于stack exchange,提问作者xxyao
相关产品推荐
相关产品推荐

