/ / python argsort индекси на базата на множество масиви - python, sorting

python argsort индекси на базата на множество масиви - питън, сортиране

Търся функция идеално в чистpython, който е подобен на numpy.argsort, тъй като връща само списък от сортирани индекси, като оставя оригиналните масиви незасегнати, но трябва да може да сортира данните, съдържащи се в множество масиви.

Пример:

>>> names = ["xavier", "bob", "billy", "jene", "samson"]
>>> ages = [15, 32, 63, 32, 15]
>>>indexes = sort by ages and then by names
[4, 0, 1, 3, 2]
>>> for i in indexes:
>>>    print "Name", names[i]
>>>    print "Age", ages[i]

Функцията за сортиране не може да създава допълнителни данниструктури, което означава разбиране на списъци или функции като zip, са изключени. Всеки масив се състои от 5 милиона обекта, генерирайки компресирана версия на масивите, които експлодират изискванията на паметта с фактор най-малко 3. Използвайки разбирането на списък като сортирано (.. key = lambda x: (имена [x], възрасти [x] )) причинява забавяне, като сортирането отнема повече от минута, за да завърши (и изискванията за памет за създаване на тези междинни кортежи)

Досега, докато искам само да сортирам aЕдин масив е достатъчно бърз, но тъй като списъкът на индексите не знае за другите масиви, не мога да извикам няколко операции за "сортиране", както бих направил, ако имах компресирана версия на двата списъка.

Отговори:

3 за отговор № 1

Това е най-доброто, което мога да мисля. най-много intВ Python са единични, така че новият списък, създаден от първия sorted повикването не трябва да създава много по-чисто нови обекти. Секундата sorted повикването трябва да създаде по-малък списък, зависи от това колко са различни възрастите.

>>> import itertools, operator
>>> names = ["xavier", "bob", "billy", "jene", "samson"]
>>> ages = [15, 32, 63, 32, 15]
>>> itemgetter = operator.itemgetter(1)
>>> sortedAges = sorted(enumerate(ages), key=itemgetter)
>>> for k, group in itertools.groupby(sortedAges, itemgetter):
...     g = sorted([(i, names[i]) for i, _ in group], key=itemgetter)
...     for i, name in g:
...         print "Name:", name, "Age:", ages[i]
...
Name: samson Age: 15
Name: xavier Age: 15
Name: bob Age: 32
Name: jene Age: 32
Name: billy Age: 63

0 за отговор № 2

Създадох собствено решение, което работи чудесно.

Като се има предвид следният набор от данни:

groups = reversed(range(5000000))
ages = [random.randrange(0, 120) for x in groups]
names = ["foobar-%d" % random.randrange(0, 5000) for x in groups]

columns = dict(names=names,ages=ages,groups=groups)

def sort_on(col):
idxs = range(len(columns[col]))
idxs.sort(key=lambda x:columns[col][x])
return idxs