3

例えば

X=[5,6,2,3,1]
Y=[7,2,3,4,6]

Xを並べ替えます:

X=[1,2,3,5,6]

しかし、同じ相対ソートを Y に適用して、数値が以前と同じ相対的な位置にとどまるようにします。

Y=[6,3,4,7,2]

これが理にかなっていることを願っています!

4

4 に答える 4

8

通常、これにはzip- sort-unzipを行います

>>> X = [5,6,2,3,1]
>>> Y = [7,2,3,4,6]

次に、それらを並べ替えます。

>>> sorted(zip(X,Y))
[(1, 6), (2, 3), (3, 4), (5, 7), (6, 2)]

それを「解凍」とペアにします(zip(*...)

>>> zip(*sorted(zip(X,Y)))
[(1, 2, 3, 5, 6), (6, 3, 4, 7, 2)]

あなたが解凍できるもの:

>>> X,Y = zip(*sorted(zip(X,Y)))
>>> X
(1, 2, 3, 5, 6)
>>> Y
(6, 3, 4, 7, 2)

これtupleでオブジェクトの代わりになりlistましたが、本当に必要な場合は元に戻すことができます。


コメントで指摘されているように、これにより、並べ替えの 2 番目のリストに非常にわずかに依存することになります。リストを検討してください。

X = [1,1,5,7] #sorted already
Y = [2,1,4,6] #Not already sorted.

上記の「レシピ」を使用すると、1日の終わりに次のものが得られます。

X = (1,1,5,7)
Y = (1,2,4,6) 

これは予想外かもしれません。keyこれを修正するには、引数を に渡すことができますsorted:

from operator import itemgetter
X,Y = zip(*sorted(zip(X,Y),key=itemgetter(0)))

デモ:

>>> X
[1, 1, 5, 7]
>>> Y
[2, 1, 4, 6]
>>> XX,YY = zip(*sorted(zip(X,Y)))
>>> XX
(1, 1, 5, 7)
>>> YY
(1, 2, 4, 6)
>>> from operator import itemgetter
>>> XX,YY = zip(*sorted(zip(X,Y),key=itemgetter(0)))
>>> XX
(1, 1, 5, 7)
>>> YY
(2, 1, 4, 6)
于 2012-12-19T14:52:41.260 に答える
4

別のアイデア:

>>> d = dict(zip(Y, X))
>>> sorted(Y, key=d.get)
[6, 3, 4, 7, 2]

ソート中に対応する値Xをキーとして使用するだけYです。

于 2012-12-19T14:57:52.717 に答える
2

重複したアイテムがあっても順序を維持する方法は次のとおりです。

def argsort(seq):
    '''
    >>> seq = [1,3,0,4,2]
    >>> index = argsort(seq)
    [2, 0, 4, 1, 3]

    Given seq and the index, you can construct the sorted seq:
    >>> sorted_seq = [seq[x] for x in index]
    >>> assert sorted_seq == sorted(seq)

    Given the sorted seq and the index, you can reconstruct seq:
    >>> assert [sorted_seq[x] for x in argsort(index)] == seq
    '''
    return sorted(range(len(seq)), key=seq.__getitem__)

X = (1,1,5,7)
Y = (1,2,4,6)
index = argsort(X)
print([Y[i] for i in index])

収量

[1, 2, 4, 6]

速度に関しては、 orusing_argsortよりも速いようです:using_zipusing_dict

def using_argsort():
    index = argsort(X)
    return [X[i] for i in index], [Y[i] for i in index]

def using_zip():
    return zip(*sorted(zip(X,Y), key = operator.itemgetter(0)))

def using_dict():
    d = dict(zip(Y,X))
    return sorted(X), sorted(Y, key = d.get)

X = [5,6,2,3,1]*1000
Y = [7,2,3,4,6]*1000

In [18]: %timeit using_argsort()
1000 loops, best of 3: 1.55 ms per loop

In [19]: %timeit using_zip()
1000 loops, best of 3: 1.65 ms per loop

In [21]: %timeit using_dict()
100 loops, best of 3: 2 ms per loop
于 2012-12-19T15:04:08.143 に答える
0

x と y の要素数は同じであると仮定しています。x を並べ替えるときは、x.swap(i,j) のように 2 つの値を交換するたびに、y.swap(i,j) も実行します。ところで、私は python を知らないので、これは python 構文ではありません。

于 2012-12-19T14:57:32.670 に答える