不用scipy.stats里的rankdata function,设计一个函数得到最后有每一列平均排名的表

问题遇到的现象和发生背景

将表中的值按行作排名,再将每列的排名作平均,得到每一列的平均排名。相当于两个步骤:第一步是给每一行的值排名次,得到一个排名表。第二步是按列平均第一步得到的排名表。排名次的依据是,值越大,名次越前。

img


img


要通过以下测试
def test_average_rank_set1():

# two simple tests with three columns and three rows
T1 = [[2,4,6], [1,4,9], [3,6,9]]
assert allclose(average_rank(T1), [3,2,1])
T2 = [[2,4,6], [4,6,2], [6,2,4]]
assert allclose(average_rank(T2), [2,2,2])
# more rows
T3 = [[2,4,6], [-1,0,1], [4,6,2], [0,-1,1], [6,2,4]]
assert allclose(average_rank(T3), [(1+3+2+2+3)/5,(2+2+3+3+1)/5,(3+1+1+1+2)/5])
# floating point values:
import math
T4 = [[math.pi/4,math.pi/2,math.pi], [math.pi/2,math.pi,math.pi/4],
      [3*math.pi,math.pi,2*math.pi]]
assert allclose(average_rank(T4), [2,2,2])
# if there are no columns, returned list should be empty
assert average_rank([[]]) == []
print("all set 1 tests passed")

def test_average_rank_set2():

# some examples with ties
T1 = [[2,2,6,6], [4,4,4,4]]
assert allclose(average_rank(T1), [3,3,2,2])
T2 = [[0,0,0,0], [1,1,1,1], [1.5,1.5,1.5,1.5]]
assert allclose(average_rank(T2), [2.5,2.5,2.5,2.5])
T3 = [[0,0,0,0], [1,1,1,1], [1.5,1.6,1.5,1.5]]
assert allclose(average_rank(T3), [8/3,2,8/3,8/3])
# example from the homework specification:
model_data = [[40,571,353,9,95,41,1428,350],
              [16,200,108,2,495,434,88,0],
              [7,352,216,9,1201,1897,9,0],
              [10,187,202,280,704,215,47,0],
              [52,616,204,2,47,17,122,5],
              [4,147,146,0,3646,536,0,0],
              [80,914,373,4,45,2,161,60],
              [67,406,778,1,9,2,3,30],
              [52,635,303,1,5,0,5,860],
              [121,712,595,0,19,0,1,53],
              [51,1914,449,0,29,18,4,50]]
flipped = [[row[c] for row in model_data] for c in range(len(model_data[0]))]
assert allclose(average_rank(flipped), [4.1875, 6.75, 5.75, 6.3125, 5.75, 8.1875, 4.0625, 6.5, 6.4375, 6.1875, 5.875])
print("all set 2 tests passed")

def allclose(s1, s2):

assert len(s1) == len(s2)
return all([abs(s1[i] - s2[i]) < 1e-6 for i in range(len(s1))])