Как вы строите массив, пригодный для сортировки по пустякам? - PullRequest
1 голос
/ 18 февраля 2009

Мне нужно отсортировать два массива одновременно, или, скорее, мне нужно отсортировать один из массивов и принести с ним соответствующий элемент соответствующего массива при сортировке. То есть, если массив [(5, 33), (4, 44), (3, 55)] и я сортирую по первой оси (помечена ниже dtype = 'alpha'), тогда я хочу: [(3.0, 55.0 ) (4,0, 44,0) (5,0, 33,0)]. Это действительно большие наборы данных, и мне нужно сначала отсортировать (для скорости nlog (n)), прежде чем я сделаю некоторые другие операции. Я не знаю, как правильно объединить два моих отдельных массива, чтобы алгоритм сортировки работал. Я думаю, что моя проблема довольно проста. Я пробовал три разных метода:

import numpy
x=numpy.asarray([5,4,3])
y=numpy.asarray([33,44,55])

dtype=[('alpha',float), ('beta',float)]

values=numpy.array([(x),(y)])
values=numpy.rollaxis(values,1)
#values = numpy.array(values, dtype=dtype)
#a=numpy.array(values,dtype=dtype)
#q=numpy.sort(a,order='alpha')
print "Try 1:\n", values

values=numpy.empty((len(x),2))
for n in range (len(x)):
        values[n][0]=y[n]
        values[n][1]=x[n]
print "Try 2:\n", values
#values = numpy.array(values, dtype=dtype)
#a=numpy.array(values,dtype=dtype)
#q=numpy.sort(a,order='alpha')

###
values = [(x[0], y[0]), (x[1],y[1]) , (x[2],y[2])]
print "Try 3:\n", values
values = numpy.array(values, dtype=dtype)
a=numpy.array(values,dtype=dtype)
q=numpy.sort(a,order='alpha')

print "Result:\n",q

Я прокомментировал первую и вторую попытки, потому что они создают ошибки, я знал, что третья будет работать, потому что это отражало то, что я видел, когда был RTFM. Учитывая массивы x и y (которые очень велики, приведены только примеры), как мне построить массив (называемые значениями), который может быть правильно вызван numpy.sort?

*** Zip отлично работает, спасибо. Дополнительный вопрос: как я могу позже снова разархивировать отсортированные данные в два массива?

Ответы [ 6 ]

6 голосов
/ 18 февраля 2009

Я думаю, что вы хотите, это функция почтового индекса. Если у вас есть

x = [1,2,3]
y = [4,5,6]

, затем zip(x,y) == [(1,4),(2,5),(3,6)]

Таким образом, ваш массив может быть построен с использованием

a = numpy.array(zip(x,y), dtype=dtype)
3 голосов
/ 10 апреля 2010

zip() может быть неэффективным для больших массивов. numpy.dstack() может использоваться вместо zip:

ndx = numpy.argsort(x)
values = numpy.dstack((x[ndx], y[ndx]))
3 голосов
/ 05 июля 2009

Саймон предложил argsort в качестве альтернативного подхода; Я бы порекомендовал это как путь. Нет беспорядочного слияния, сжатия или распаковки: просто доступ по индексу.

idx = numpy.argsort(x)
ans = [ (x[idx[i]],y[idx[i]]) for i in idx]
3 голосов
/ 18 февраля 2009

для вашего бонусного вопроса - zip на самом деле тоже расстегивает молнию:

In [1]: a = range(10)
In [2]: b = range(10, 20)
In [3]: c = zip(a, b)
In [4]: c
Out[4]: 
[(0, 10),
 (1, 11),
 (2, 12),
 (3, 13),
 (4, 14),
 (5, 15),
 (6, 16),
 (7, 17),
 (8, 18),
 (9, 19)]
In [5]: d, e = zip(*c)
In [6]: d, e
Out[6]: ((0, 1, 2, 3, 4, 5, 6, 7, 8, 9), (10, 11, 12, 13, 14, 15, 16, 17, 18, 19))
2 голосов
/ 18 февраля 2009

Я думаю, что вам просто нужно указать ось, по которой вы сортируете, когда вы сделали свой последний ndarray. В качестве альтернативы argsort один из исходных массивов, и у вас будет индексный массив, который вы можете использовать для поиска по x и y, что может означать, что вам вообще не нужны значения.

(scipy.org, кажется, сейчас недоступен, или я бы опубликовал ссылку на некоторые документы)

Учитывая, что ваше описание не совсем соответствует вашему фрагменту кода, трудно сказать с уверенностью, но я думаю, что вы слишком усложнили создание вашего массива.

1 голос
/ 18 февраля 2009

Я не смог получить работающее решение, используя функцию Numpy sort, но вот еще кое-что, что работает:

import numpy
x = [5,4,3]
y = [33,44,55]
r = numpy.asarray([(x[i],y[i]) for i in numpy.lexsort([x])])

lexsort возвращает перестановку индексов массива, которая размещает строки в отсортированном порядке. Если вы хотите, чтобы результаты сортировались по нескольким ключам, например, на x, а затем на y, используйте numpy.lexsort([x,y]) вместо.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...