[英]How to get ranks from a sample in a list of values?
我是 Python 新手,在纸上有一个非常简单的问题,但在 Python 中对我来说很难。
我有两个值样本(它们是列表):
X = [2, 2, 4, 6]
Y = [1, 3, 4, 5]
我有一个串联的列表,排序为
Z = [ 1 , 2 , 2 , 3 , 4 , 4 , 5 , 6]
#rank: 1 2.5 4 5.5 7 8
我想得到Z
中X
值的等级总和。 对于这个例子,Z 中2.5 + 2.5 + 5.5 + 8 = 18.5
和 6 的等级是2.5 + 2.5 + 5.5 + 8 = 18.5
( Z
中Y
值的等级为1 + 4 + 5.5 + 7 = 17.5
)
这是我所做的,但它不适用于这些列表 X 和 Y(如果每个值只出现一次,它就起作用)
def funct(X, Z):
rank = []
for i in range(len(Z)):
for j in range(len(X)):
if Z[i] == X[j]:
rank = rank + [(i+1)]
print(sum(rank))
return
我想用不太复杂的函数来解决我的问题(只有循环和非常简单的解决方法)。
对组合列表进行排序后,您可以使用字典来跟踪排名总和和计数。
X = [2, 2, 4, 6]
Y = [1, 3, 4, 5]
Z = sorted(X + Y)
ranksum = {}
counts = {}
for i, v in enumerate(Z):
ranksum[v] = ranksum.get(v, 0) + (i + 1) # Add
counts[v] = counts.get(v, 0) + 1 # Increment count
然后,当您想查找元素的排名时,您需要ranksum[v] / count[v]
。
r = [ranksum[x] / counts[x] for x in X]
print(r)
# Out: [2.5, 2.5, 5.5, 8]
这是如何构建排名列表的解决方案:
X = ...
Y = ...
Z = sorted(X + Y)
rank = [1]
z = Z[:1]
for i, e in enumerate(Z[1:], start=2):
if e == z[-1]:
rank[-1] += 0.5
else:
rank.append(i)
z.append(e)
现在您可以将其转换为字典:
ranks = dict(zip(z, rank))
这将使查找更容易:
sum(ranks[e] for e in X)
这是另一个选项,您可以在其中构建排名索引的字典,然后从那里创建一个排名字典:
from collections import defaultdict
X = [2, 2, 4, 6]
Y = [1, 3, 4, 5]
Z = sorted(X + Y)
rank_indexes = defaultdict(lambda: [])
for i,v in enumerate(Z):
rank_indexes[v].append(i+1)
ranks = {k:(sum(v)/len(v)) for (k,v) in rank_indexes.items()}
print("Sum of X ranks:", sum([ranks[v] for v in X]))
print("Sum of Y ranks:", sum([ranks[v] for v in Y]))
输出:
Sum of X ranks: 18.5
Sum of Y ranks: 17.5
你可以在没有 defaultdict 的情况下做同样的事情,但它稍微慢一些,我认为 Pythonic 更少:
rank_indexes = {}
for i,v in enumerate(Z):
rank_indexes.setdefault(v, []).append(i+1)
ranks = {k:(sum(v)/len(v)) for (k,v) in rank_indexes.items()}
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.