python成绩统计_检索各种列表中的元素排名,以计算其排名分数的加权平均值Python...

我已经采取简单的方法,给予同等分数的类下一个整数排名,所以class3和class2都有等级2 sorted_dict1

#!/usr/bin/env python

#Get the ranks for a list of (class, score) tuples sorted by score

#and return them in a dict

def get_ranks(sd):

#The first class in the list has rank 1

k, val = sd[0]

r = 1

rank = {k: r}

for k, v in sd[1:]:

#Only update the rank number if this value is

#greater than the previous

if v > val:

val = v

r += 1

rank[k] = r

return rank

def weighted_mean(a, b):

return (0.50*a + 0.25*b)/0.75

sorted_dict1 = [('class1', 15.17), ('class2', 15.95), ('class3', 15.95)]

sorted_dict2 = [('class2', 9.10), ('class3', 9.22), ('class1', 10.60)]

print sorted_dict1

print sorted_dict2

ranks1 = get_ranks(sorted_dict1)

ranks2 = get_ranks(sorted_dict2)

print ranks1

print ranks2

keys = sorted(k for k,v in sorted_dict1)

print [(k, weighted_mean(ranks1[k], ranks2[k])) for k in keys]

输出

[('class1', 15.17), ('class2', 15.949999999999999), ('class3', 15.949999999999999)]

[('class2', 9.0999999999999996), ('class3', 9.2200000000000006), ('class1', 10.6)]

{'class2': 2, 'class3': 2, 'class1': 1}

{'class2': 1, 'class3': 2, 'class1': 3}

[('class1', 1.6666666666666667), ('class2', 1.6666666666666667), ('class3', 2.0)]

在我提到的评论中有一个很好的方法来创建一个weighted_mean()函数w自定义权重。当然,我们可能只是将权重作为附加参数传递给weighted_mean(),但这会使weighted_mean()的调用比需要的更加混乱,从而使程序难以阅读。

诀窍是使用将自定义权重作为参数并返回所需函数的函数。从技术上讲,这种功能制作功能被称为closure。

下面是如何做到这一点的简短演示。

#!/usr/bin/env python

#Create a weighted mean function with weights w1 & w2

def make_weighted_mean(w1, w2):

wt = float(w1 + w2)

def wm(a, b):

return (w1 * a + w2 * b)/wt

return wm

#Make the weighted mean function

weighted_mean = make_weighted_mean(1, 2)

#Test

print weighted_mean(6, 3)

print weighted_mean(3, 9)

输出

4.0

7.0

这里的第一个程序的更新版本高于处理sorted_dict列出任意数量。它使用原始的get_ranks()函数,但它使用比上述示例更复杂的闭包来执行数据列表(或元组)上的加权平均值。

#!/usr/bin/env python

''' Weighted means of ranks

From https://stackoverflow.com/q/29413531/4014959

Written by PM 2Ring 2015.04.03

'''

from pprint import pprint

#Create a weighted mean function with weights from list/tuple weights

def make_weighted_mean(weights):

wt = float(sum(weights))

#A function that calculates the weighted mean of values in seq

#weighted by the weights passed to make_weighted_mean()

def wm(seq):

return sum(w * v for w, v in zip(weights, seq))/wt

return wm

#Get the ranks for a list of (class, score) tuples sorted by score

#and return them in a dict

def get_ranks(sd):

#The first class in the list has rank 1

k, val = sd[0]

r = 1

rank = {k: r}

for k, v in sd[1:]:

#Only update the rank number if this value is

#greater than the previous

if v > val:

val = v

r += 1

rank[k] = r

return rank

#Make the weighted mean function

weights = [0.50, 0.25]

weighted_mean = make_weighted_mean(weights)

#Some test data

sorted_dicts = [

[('class1', 15.17), ('class2', 15.95), ('class3', 15.95), ('class4', 16.0)],

[('class2', 9.10), ('class3', 9.22), ('class1', 10.60), ('class4', 11.0)]

]

print 'Sorted dicts:'

pprint(sorted_dicts, indent=4)

all_ranks = [get_ranks(sd) for sd in sorted_dicts]

print '\nAll ranks:'

pprint(all_ranks, indent=4)

#Get a sorted list of the keys

keys = sorted(k for k,v in sorted_dicts[0])

#print '\nKeys:', keys

means = [(k, weighted_mean([ranks[k] for ranks in all_ranks])) for k in keys]

print '\nWeighted means:'

pprint(means, indent=4)

输出

Sorted dicts:

[ [ ('class1', 15.17),

('class2', 15.949999999999999),

('class3', 15.949999999999999),

('class4', 16.0)],

[ ('class2', 9.0999999999999996),

('class3', 9.2200000000000006),

('class1', 10.6),

('class4', 11.0)]]

All ranks:

[ { 'class1': 1, 'class2': 2, 'class3': 2, 'class4': 3},

{ 'class1': 3, 'class2': 1, 'class3': 2, 'class4': 4}]

Weighted means:

[ ('class1', 1.6666666666666667),

('class2', 1.6666666666666667),

('class3', 2.0),

('class4', 3.3333333333333335)]

而且这里有get_ranks()的替代版本,跳过等级号码如果有两个或多个类均居同在一个列表

def get_ranks(sd):

#The first class in the list has rank 1

k, val = sd[0]

r = 1

rank = {k: r}

#The step size from one rank to the next. Normally

#delta is 1, but it's increased if there are ties.

delta = 1

for k, v in sd[1:]:

#Update the rank number if this value is

#greater than the previous.

if v > val:

val = v

r += delta

delta = 1

#Otherwise, update delta

else:

delta += 1

rank[k] = r

return rank

这里的输出该程序使用get_ranks()的替代版本:

Sorted dicts:

[ [ ('class1', 15.17),

('class2', 15.949999999999999),

('class3', 15.949999999999999),

('class4', 16.0)],

[ ('class2', 9.0999999999999996),

('class3', 9.2200000000000006),

('class1', 10.6),

('class4', 11.0)]]

All ranks:

[ { 'class1': 1, 'class2': 2, 'class3': 2, 'class4': 4},

{ 'class1': 3, 'class2': 1, 'class3': 2, 'class4': 4}]

Weighted means:

[ ('class1', 1.6666666666666667),

('class2', 1.6666666666666667),

('class3', 2.0),

('class4', 4.0)]

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值