【问题标题】:Ranking a list in python with None values在 python 中使用 None 值对列表进行排名
【发布时间】:2021-01-20 22:36:35
【问题描述】:

我正在尝试以一种有效的方式查找列表项的排名。问题是当我有一个 None 值时。

我当前的解决方案根据reverse 值将 None 放在排名的顶部或底部:

tmp = [29.84087, 34.3745, 34.91104, 35.72471, 19.31632, 728.1475, None, 404.3762, None]

[sorted(values, key=lambda x: (x is None, x), reverse=False).index(x) + 1 for x in values]

-> [2, 3, 4, 5, 1, 7, 8, 6]

我应该如何更改排名代码以获得 None for None 值?

所需的输出如下所示:

[2, 3, 4, 5, 1, 7, None, 6, None]

【问题讨论】:

  • 您希望None 值出现在结果中,还是删除它们?
  • 我希望它们在结果中为无。
  • 这是您的预期结果吗? [2, 3, 4, 5, 1, 7, None, 6]
  • 您的期望是什么,因为我不清楚?
  • 您应该通过不为值列表中的每个项目创建排序列表来节省大量计算

标签: python python-3.x sorting


【解决方案1】:

在列表推导中使用 conditional expressions 将 None 值保持为 None。

通过在列表理解之前一次性进行排序操作,我们避免了很多不必要的计算。

values = [29.84087, 34.3745, 34.91104, 35.72471, 19.31632, 728.1475, None, 404.3762]
sorted_v = sorted(x for x in values if x is not None)
ranks = [None if x is None else sorted_v.index(x) + 1 for x in values]
# [2, 3, 4, 5, 1, 7, None, 6]

【讨论】:

  • 谢谢!它有效,是否有任何解决方法可以使它成为一个衬里?
  • @MehdiZare 用分号替换换行符
  • :) 我的意思是一次操作
  • @MehdiZare 我找不到在每次迭代中对列表进行排序的方法。
  • @MehdiZare 我能问一下为什么只有一次手术很重要吗?你不能为它创建一个函数吗
【解决方案2】:

这个怎么样?

import numpy as np
tmp =  [29.84087, 34.3745, 34.91104, 35.72471, 19.31632, 728.1475, None, 404.3762, None]
tmp_np = np.array(tmp, dtype=np.float)

mask = ~np.isnan(tmp_np)

rank_maksed = np.empty_like(tmp_np[mask])
np.put_along_axis(rank_maksed, 
                  np.argsort(tmp_np[mask]),
                  np.arange(np.sum(mask))+1,
                  axis=0)
rank = np.full_like(tmp_np, np.nan)
rank[mask] = rank_maksed
print(rank)
# --> array([ 2.  3.  4.  5.  1.  7. nan  6. nan])

注意:在@pakpe 的评论后更新

【讨论】:

  • 这会在错误的索引处返回 nan。它应该在索引 6,而不是 5。
【解决方案3】:

Mehdi,以下列表推导会从您的列表中删除 None,对列表进行排序,并返回一个排名列表。在第二行,您将 None 的排名插入到排名列表中。

ranks = [sorted([item for item in tmp if item]).index(item) + 1 for item in tmp if item]
ranks.insert(tmp.index(None), None)


#print(ranks) >> [2, 3, 4, 5, 1, 7, None, 6]

【讨论】:

  • 如果tmp 中有多个None,这将不起作用。
  • @Jolbas 我们假设列表中的每个条目都是唯一的,否则对它们进行排名将毫无意义。所以 None 大概只出现一次,任何其他值也是如此。
  • 如果某些项目的值相等,是否会有tie?那么set 可以在这种情况下提供帮助。只需 0.02 美元(那时可能排名靠前)
  • @DanielHao 我认为这个问题不包括 tue 场景,因为作者自己的解决方案(以及我们所有人的解决方案)都是基于索引的,不适用于平局。
  • 为什么说如果有平局,排名就没有意义,OP的解决方案也行不通?那不就是Standard competition ranking ("1224" ranking)吗?
猜你喜欢
  • 1970-01-01
  • 2012-11-26
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2021-07-12
  • 2018-01-26
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多