[英]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))
现在一切都对a
和b
。
由于 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.