繁体   English   中英

熊猫排名负整数和正整数,多列

[英]Pandas rank negative and positive integer, multiple columns

我不是数学家,我是一名财务人员,面临一个最好描述如下的问题:我正在寻找有关如何对两个整数系列进行排名的建议,其中一个整数在正数和正数中都有一个域负值,另一个只有正域。

期望 X 的高正值,不期望高负值。

Y 被限制为正数,不希望有高值,希望有低值。

到目前为止,我最好的猜测是:

在正域中,这个比率是有意义的:X/Y

在负域 (1/X*Y) 中往往有意义,但我怀疑它强加了不对称性。

让我们假设这是 X 和 Y 的理想排序系列

X, Y, rank
10,100, 6
10,1000, 5.5
1,100, 5.5
1,1000, 4
-1,100, 3
-1,1000, 2.5
-10,100, 2.5
-10,1000, 1

5.5 和 2.5 在数字和概念上是相似的(无差异)。

有没有一个函数可以用来对这个逻辑进行排序和捕获?

一个硬性限制是正 X 总是比负 X 好,因此 X 的负值永远不应高于 X 的正值。

如果您知道 X 系列的最小值,那么最好使用以下分数:

(X + Xmin)/Y # Adding the minimal value as an offset is a standard procedure to obtain only positive values. 

如果您想更进一步,您甚至可以通过执行以下操作来标准化 X 和 Y:

X = (X + Xmin) / Xmax
Y = (Y + Ymin) / Ymax

然后执行 score = X/Y

我使用series.rank()如下:

df['new_rank']=df.X.rank(method='dense',ascending=True)+df.Y.rank(method='dense',ascending=False)-1
print(df)

    X     Y  rank  new_rank
0  10   100   6.0       5.0
1  10  1000   5.5       4.0
2   1   100   5.5       4.0
3   1  1000   4.0       3.0
4  -1   100   3.0       3.0
5  -1  1000   2.5       2.0
6 -10   100   2.5       2.0
7 -10  1000   1.0       1.0

提供的链接中的文档说明。

您使用X/Y假设(如果 Y 接受 0,请确保您使用 X/1+Y)是正确的。 现在的问题是你对 X 和 Y 有多大的重视????我的意思是,假设(aX)* (b*(1/y))现在一切都对ab

由于 X 的重要性随着其值的增加而增加,您甚至可以使用 x^3 并惩罚更高的负项并奖励更高的正项。

来到 y, 1/(1+y^2) if(y accepts 0, 1/0 is undefined 所以加1。)

您还在寻找解决方案吗? 如果它仍然相关,我可以发布。 简而言之,您首先需要分离问题 a) 拆分指标和 b) 计算分数。 指标高到低的比率排名越高,排名越高(例如毛利率、ROE、ROA)。 对于这个组,您无需担心负数,因为当按降序排序时,它们将获得您期望的适当权重。 第二组比率需要分批到低到高类别中(例如市盈率、市账率等),您应该对它们进行预处理,以惩罚该子项的负数团体。 这需要更改原始数据,因此您应该为预处理和排名制作 df 的副本。 我建议使用 minmax 缩放作为分数,因为使用对 minmax 缩放比例的排序,只需对这个子组进行小幅调整即可以适当的方式对其进行评分。 这是处理预处理和对低到高组中的指标进行评分的部分解决方案。 注意:如果你真的想给 NaN 值一个平均值,你可以在我这里处理负值的函数下方或上方添加另一个 lambda 函数。 此处的负值与最高值相加,因此将获得最低分。 在我将其用于 49 个财务比率时,我离开 NaN 并只对分数求和。 否则,即使缺少大部分数据,一行或公司也可以获得合理的值,而对于分数的总和,它在所有比率上仍然显得不那么有吸引力。 `import pandas as pd import numpy as np def main():

df = pd.DataFrame({'A':[-14.00,90.20,np.nan,96.27,91.21],
                   'B':[103.02,-17.26,110.35,114.23,114.68], 
                   'C':['big','small','big','small','small']})
mycolumns=['A', 'B']
df_sub=pd.DataFrame(columns=mycolumns)      #used to protect the original data
for mycol in mycolumns:
    df_sub[mycol]=(df[mycol])
    cmax=df_sub[mycol].max()
    df_sub[mycol] = df_sub[mycol].apply(lambda x : x if x > 0 else (cmax-x))
    df[f'{mycol} Score'] = 1-(df_sub[mycol] - df_sub[mycol].min()) / (df_sub[mycol].max() - df_sub[mycol].min())
    print(f'Original Data with Scores:\n {df},\nScaled Data: \n {df_sub}')`

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM