Python - 如何使用用户定义的函数执行间接排序?

时间:2016-03-06 22:08:44

标签: python sorting numpy

numpy.argsort返回一个排序列表来执行间接排序,但它似乎不接受用户定义的函数来比较两个元素。

我想知道如何根据与用户定义函数的比较来获取排序列表。

就我而言,我有一张结果表:

a = [[1,2,3,5,6,7,8],[4,6,2,5,6,3,4],...]

我的比较功能是:

def argMedian(A):
    s   = np.array([sum(A[:i+1]) for i in range(Nmentions)])
    mid = float(s[Nmentions-1])/2
    return np.argwhere(mid < s)[0][0]

def tieBreaking(A, B):
Ac = A
Bc = B
medA = argMedian(Ac)
medB = argMedian(Bc)
while medA == medB:
    Ac[medA] -= 1
    Bc[medB] -= 1
    medA = argMedian(Ac)
    medB = argMedian(Bc)
return 1 if medA > medB else -1

这是majority judgment的实现。列表包含每个年级的投票数。如果两个列表之间的中位数相等,则删除两个列表的中间投票,并再次测试中值的比较。在这里,我认为指数0是最佳等级,而指数7是最差等级。

我需要进行间接排序,因为我想知道排名。

3 个答案:

答案 0 :(得分:1)

如果您使用的是Python&gt; = 3.4,则可以使用statistics.median_low()

from random import randrange
from statistics import median_low

a = [[randrange(8) for _ in range(7)] for _ in range(10)]

print("unsorted")
for item in a:
    print(item)

a.sort(key=median_low)

print("\nsorted")
for item in a:
    print(item)

输出:

unsorted
[4, 2, 2, 1, 4, 7, 4]
[2, 2, 2, 7, 5, 5, 6]
[3, 0, 0, 5, 5, 3, 1]
[4, 7, 6, 2, 6, 7, 3]
[4, 7, 7, 1, 2, 7, 7]
[6, 2, 6, 5, 6, 7, 2]
[7, 1, 6, 0, 0, 7, 1]
[0, 5, 1, 2, 1, 7, 7]
[2, 7, 6, 7, 5, 4, 7]
[6, 5, 2, 3, 5, 0, 3]

sorted
[7, 1, 6, 0, 0, 7, 1]
[0, 5, 1, 2, 1, 7, 7]
[3, 0, 0, 5, 5, 3, 1]
[6, 5, 2, 3, 5, 0, 3]
[4, 2, 2, 1, 4, 7, 4]
[2, 2, 2, 7, 5, 5, 6]
[4, 7, 6, 2, 6, 7, 3]
[6, 2, 6, 5, 6, 7, 2]
[2, 7, 6, 7, 5, 4, 7]
[4, 7, 7, 1, 2, 7, 7]

编辑完整备用解决方案:

考虑按如下方式对列表进行排序: 1.找到列表的median_low并将其移动到列表的前面 2.找到列表[1:]的median_low并将其移动到第二个点 3.找到list [2:] ...

的median_low

您可以按中位数对原始列表进行排序,或创建按中位数对元素进行排序的键。

def def keyfunc(x):
    t = x[:]
    return [t.pop(t.index(median_low(t))) for _ in range(len(t))]

a = [
    [4, 2, 2, 1, 4, 7, 4],
    [2, 2, 2, 7, 5, 5, 6],
    [3, 0, 0, 5, 5, 3, 1],
    [7, 1, 6, 0, 0, 6, 1],    # tie for first four rounds, but then wins
    [4, 7, 6, 2, 6, 7, 3],
    [6, 2, 6, 5, 6, 7, 2],
    [7, 1, 6, 0, 0, 7, 1],    # tie for first four rounds
    [0, 5, 1, 2, 1, 7, 7],
    [2, 7, 6, 7, 5, 4, 7],
    [6, 5, 2, 3, 5, 0, 3]
]

a.sort(key=keyfunc)

print("\nsorted")
for item in a:
    print(item)

输出:

sorted
[7, 1, 6, 0, 0, 6, 1]
[7, 1, 6, 0, 0, 7, 1]
[0, 5, 1, 2, 1, 7, 7]
[3, 0, 0, 5, 5, 3, 1]
[6, 5, 2, 3, 5, 0, 3]
[4, 2, 2, 1, 4, 7, 4]
[2, 2, 2, 7, 5, 5, 6]
[4, 7, 6, 2, 6, 7, 3]
[6, 2, 6, 5, 6, 7, 2]
[2, 7, 6, 7, 5, 4, 7]

答案 1 :(得分:0)

您不需要使用numpy对列表中的元素进行排序。您可以为列表或sorted()添加sort()函数。如果需要,在那里定义自定义比较器。

答案 2 :(得分:0)

对于使用基本python计算间接排序,几乎没有技巧。他们在Equivalent of Numpy.argsort() in basic python?进行了比较。

采用最快的解决方案,可以添加比较功能。

在Python 2.7中:

sorted(range(len(results)), cmp=tieBreaking, key=results.__getitem__)

在Python 3中,应该注意cmp已经消失,但函数cmp_to_key可以替换它。