同じ数の要素を持つold
との2 つのリストがあります。new
n
パラメータとして取り、同じ場所にある2つのリストの要素を(インデックスで)比較し、最大の違いを見つけて、それらの要素n
のインデックスを返す効率的な関数を作成しようとしています。n
これは、値でソートされた辞書で解決するのが最善だと思っていましたが、Python では利用できません(それを提供するライブラリは知りません)。おそらく、より良い解決策がありますか?
同じ数の要素を持つold
との2 つのリストがあります。new
n
パラメータとして取り、同じ場所にある2つのリストの要素を(インデックスで)比較し、最大の違いを見つけて、それらの要素n
のインデックスを返す効率的な関数を作成しようとしています。n
これは、値でソートされた辞書で解決するのが最善だと思っていましたが、Python では利用できません(それを提供するライブラリは知りません)。おそらく、より良い解決策がありますか?
「 n最大」と思うときはいつでも、考えてheapq
ください。
>>> import heapq
>>> import random
>>> l1 = [random.randrange(100) for _ in range(100)]
>>> l2 = [random.randrange(100) for _ in range(100)]
>>> heapq.nlargest(10, (((a - b), a, b) for a, b in zip(l1, l2)))
[(78, 99, 21), (75, 86, 11), (69, 90, 21), (69, 70, 1), (60, 86, 26), (55, 95, 40), (52, 56, 4), (48, 98, 50), (46, 80, 34), (44, 81, 37)]
これにより、O(n log x) 時間で x 個の最大のアイテムが見つかります。ここで、n はリスト内のアイテムの総数です。ソートは O(n log n) 時間でそれを行います。
上記が実際にあなたが求めたことをしないことが私に起こりました。インデックスが欲しい!それでも非常に簡単です。abs
差の絶対値が必要な場合は、ここでも使用します。
>>> heapq.nlargest(10, xrange(len(l1)), key=lambda i: abs(l1[i] - l2[i]))
[91, 3, 14, 27, 46, 67, 59, 39, 65, 36]
リスト内の要素の数がそれほど多くないと仮定すると、それらすべてを区別し、並べ替えて、最初のものを選択することができますn
:
print sorted((abs(x-y) for x,y in zip(old, new)), reverse=True)[:n]
これはO(k log k)
、k
元のリストの長さです。
n
が よりも大幅に小さい場合、モジュールが提供する関数k
を使用するのが最善の方法です。nlargest
heapq
import heapq
print heapq.nlargest(n, (abs(x-y) for x,y in zip(old, new))
これは、O(k log n)
の代わりにO(k log k)
どちらが重要になるかになりk >> n
ます。また、リストが非常に大きい場合は、通常の関数itertools.izip
の代わりに使用した方がよいでしょう。zip
これはnumpyで一緒にハッキングされたソリューションです (免責事項、私は numpy の初心者なので、これを行うためのより洗練された方法があるかもしれません)。どのステップも組み合わせていないので、各ステップが何をしていたかは非常に明確です。最終的な値は、元のリストのインデックスを最大デルタの順に並べたリストです。上位 n を選択するのは簡単sorted_inds[:n]
で、各リストまたはデルタ リストから値を取得するのは簡単です。
パフォーマンスが他のソリューションとどのように比較されるかはわかりません。明らかに、このような小さなデータセットでは表示されませんが、numpy は非常に高速であることを理解しているので、実際のデータセットでテストする価値があるかもしれません。数値配列操作用。
import numpy
list1 = numpy.array([1, 2, 3, 4, 5, 6, 7, 8, 9])
list2 = numpy.array([9, 8, 7, 6, 5, 4, 3, 2, 1])
#Caculate the delta between the two lists
delta = numpy.abs(numpy.subtract(list1, list2))
print('Delta: '.ljust(20) + str(delta))
#Get a list of the indexes of the sorted order delta
sorted_ind = numpy.argsort(delta)
print('Sorted indexes: '.ljust(20) + str(sorted_ind))
#reverse sort
sorted_ind = sorted_ind[::-1]
print('Reverse sort: '.ljust(20) + str(sorted_ind))
Delta: [8 6 4 2 0 2 4 6 8]
Sorted indexes: [4 3 5 2 6 1 7 0 8]
Reverse sort: [8 0 7 1 6 2 5 3 4]
>>> l = []
... for i in itertools.starmap(lambda x, y: abs(x-y), itertools.izip([1,2,3], [100,102,330])):
... l.append(i)
>>> l
5: [99, 100, 327]
itertools
反復作業に便利です。からにstarmap
変換tuples
し*args
ます。参考までに。With max
関数を使用すると、目的の結果を得ることができます。index
関数は位置を見つけるのに役立ちます。
l.index(max(l)
>>> l.index(max(l))
6: 2
あなたの質問から、これがあなたが望むものだと思います:
difference.py で
l1 = [15,2,123,4,50]
l2 = [9,8,7,6,5]
l3 = zip(l1, l2)
def f(n):
diff_val = 0
index_val = 0
l4 = l3[:n]
for x,y in l4:
if diff_val < abs(x-y):
diff_val = abs(x-y)
elem = (x, y)
index_val = l3.index(elem)
print "largest diff: ", diff_val
print "index of values:", index_val
n = input("Enter value of n:")
f(n)
実行:
[avasal@avasal ]# python difference.py
Enter value of n:4
largest diff: 116
index of values: 2
[avasal@avasal]#
これがあなたが望むものではない場合は、質問をもう少し詳しく説明することを検討してください..