2017-01-31 6 views
0

を可能にすると、私はこのようなリストを持っているとしましょうランク番号のリスト、ネクタイ

ここ
newIndexVertList = [0, 1, 2, 2, 1, 4, 5, 5, 4, 3, 7, 6] 

、変換が基づいています元のリストの昇順の番号の位置。したがって、新しいリスト番号がロジックに基づいて置き換えられます。

以下
0 --> 0 0th position in sorted list 
1 --> 1 1st position in sorted list 
2 --> 2 2nd position in sorted list 
3 --> 3 3rd position in sorted list 
20 --> 4 4th position in sorted list 
21 --> 5 5th position in sorted list 
22 --> 6 6th position in sorted list 
23 --> 7 7th position in sorted list 

は、これを達成するための私のコードです:私のコードの問題です

c = 0 
for i in xrange(len(newIndexVertList)): 
    if c < newIndexVertList[i]: 
     newIndexVertList[i] = c 
     c += 1 
     continue 
    elif c == newIndexVertList[i]: 
     c += 1 
     continue 
    else: 
     continue 

# actual output: [0, 1, 2, 2, 1, 3, 4, 5, 6, 3, 7, 8] 
# expected output: [0, 1, 2, 2, 1, 4, 5, 5, 4, 3, 7, 6] 

何?これを達成するためのエレガントな方法は何ですか?

私の頂点リストは100kの範囲にあるので、私は最も速い実行を探しています。

+2

'インデックスが= [ソート(リスト(集合(頂点)))指数(V) for v in vertices]は、OPが探しているものですと思います。私は質問の言葉遣いが改善されている必要があります同意 – zinfandel

+1

さて、zinfandel答えは動作しますが、それは巨大な時間複雑さを持っています。ソート、リストへの変換、ソートされたリスト内での 'v'の設定+変換を行う頂点の反復ごとにindex(v)'が計算されます –

+0

@MoinuddinQuadri Ah、読みやすくなる一方、最速の解決策ではないかもしれません。私の頂点リストは100kの範囲にあるので、私は最も速い実行を探しているはずです。あなたの答えはより速いでしょうか? – RedForty

答えて

7

あなたがenumerate()sorted()set()を使用介して元のリスト内の位置と数をマッピングする中間dictオブジェクトの作成を介してそれを達成することができる:

>>> my_list = [0, 1, 2, 2, 1, 20, 21, 21, 20, 3, 23, 22] 
>>> num_map = {j: i for i, j in enumerate(sorted(set(my_list)))} 
#           ^^to get unique elements 
#           ^sort numbers in ascending order 

>>> [num_map[n] for n in my_list] 
[0, 1, 2, 2, 1, 4, 5, 5, 4, 3, 7, 6] 

Stefanによってコメントとして、それが中に達成することができます1行としてmap()を使用して:あなたはコメントで言及した

list(map({j: i for i, j in enumerate(sorted(set(my_list)))}.get, my_list)) 
#^type-cast `map` object to `list` for Python 3.x compatibility 
+1

'map({j:i for i、j in enumerate(sorted(my_list))}} get、my_list)' –

3

データが大きくなります(100K)A最も速い実行を探しています。あなたはnumpyの使用を検討してください:

>>> vertices = [0, 1, 2, 2, 1, 20, 21, 21, 20, 3, 23, 22] 
>>> np.unique(vertices, return_inverse=True)[1] 
array([0, 1, 2, 2, 1, 4, 5, 5, 4, 3, 7, 6]) 

ランダムに0と100の間に分布する整数の100kの長い配列の場合、これが現在受け入れ答えより速くより3倍です。

PythonのチャットルームにユーザDSMによって示唆別のパフォーマンスのオプションは、データをランク付けするscipy.statsを使用している:。

>>> import scipy.stats 
>>> (scipy.stats.rankdata(vertices, 'dense') - 1).astype(int) 
array([0, 1, 2, 2, 1, 4, 5, 5, 4, 3, 7, 6]) 
+0

Sweet!独自の機能を備えたユニークなソリューション。 – MYGz

関連する問題