Python:高速抽出の交差点の中で可能な2つの組み合わせた多数のリスト
-
20-09-2019 - |
質問
いデータセットです。9Kのリストを可変長(1-100Kのいの長さを計算するの交差点 全ての可能な2つのリストを組み合わせ このデータセットである。ご注意要素の各リストではないとして保存できセット。
その中で最も効率的な方法で行うこpython?
編集 忘れてしまったのを指定する必要があり、能力に合わせて交差点の値に対応するペアのリストが表示されます。さみんなのための迅速な対応および今回の混乱!
解決
場合に設定して保存s,例えば:
s = [set([1, 2]), set([1, 3]), set([1, 2, 3]), set([2, 4])]
を利用することができ itertools.組み合わせ しつつ、計算の交差点(ただし、アレックス指摘の通り、 combinations
はて2.6).このリストcomrehension(のコンセプトの例:
from itertools import combinations
[ i[0] & i[1] for i in combinations(s,2) ]
または、ループすることで、必要なもの:
for i in combinations(s, 2):
inter = i[0] & i[1]
# processes the intersection set result "inter"
での長さのひとつひとつに、"処理"することはできない。
l = len(inter)
このことは非常に効率的での使用を計算する反復子毎の組み合わせ、なすべてを用意する。
編集:ご注意この方法は、各設定のリスト"s"することができない setを返しま, のように機能します。のリスト自体がするだけで簡単に発電機の場合は短いる。きの遅いものの方法により異を生成するこれらの要素が必要ないの全リストのセットメモリに同時になすべきであると問題になる。
例えば、各設定する機能 gen
:
def gen(parameter):
while more_sets():
# ... some code to generate the next set 'x'
yield x
with open("results", "wt") as f_results:
for i in combinations(gen("data"), 2):
inter = i[0] & i[1]
f_results.write("%d\n" % len(inter))
編集2:するかという指標をもとに以下のredratのコメント.
ほかの迅速なソリューションしたコメントするより効率的な方法で収集の設定指標っていた、というリスト (index, set)
の代わりにリスト set
.
例と新しいフォーマット:
s = [(0, set([1, 2])), (1, set([1, 3])), (2, set([1, 2, 3]))]
の場合は建物のこのリストの計算を組み合わせくので簡単な対応を求められる。主なループにつなが
with open("results", "wt") as f_results:
for i in combinations(s, 2):
inter = i[0][1] & i[1][1]
f_results.write("length of %d & %d: %d\n" % (i[0][0],i[1][0],len(inter))
のループ i[0]
や i[1]
このタプル (index, set)
, ので、 i[0][1]
最初のセット i[0][0]
その指数です。
他のヒント
、すなわち、O(N平方)出力、いかなるアプローチは(N平方)Oより少なくなることはできません - もちろん、任意の言語で。 (Nは、あなたの質問に「9K程度」です)。すなわち、最も簡単な方法 - だから、私は本質的に速い(a)のNはあなたが必要と設定すること、及びそれらは出力を生成する上で(b)の反復処理よりも何も表示されません。 IOWます:
def lotsofintersections(manylists):
manysets = [set(x) for x in manylists]
moresets = list(manysets)
for s in reversed(manysets):
moresets.pop()
for z in moresets:
yield s & z
このコードはすでに(他のO(N平方)の要素を追加する可能性がある、スライシングを回避またはリストの前に飛び出しことで、例えば)いくつかのマイナーな最適化を追加しようとしてます。
あなたが利用できる多くのコアおよび/またはノードを持っており、並列アルゴリズムを探しているなら、それは当然の異なる場合だ - それはあなたのケースだ場合、あなたはあなたが持っているクラスタの種類、その大きさに言及することができ、どのノードとコア最高などの通信、およびことができますか?
編集:OPは気軽にコメントで述べたように、彼らは実際に(本当に、なぜ少なくとも?!仕様の、このような重要な部分を省略して交差するセットの番号が必要であること(!)それらを明確にするために、質問を編集...)、これだけにこれを変更することが必要になります:
L = len(manysets)
for i, s in enumerate(reversed(manysets)):
moresets.pop()
for j, z in enumerate(moresets):
yield L - i, j + 1, s & z
(あなたはプログレッシブ識別子は、「1から数える」する必要がある場合 - それ以外の明らかな変化を)。
しかし、それはあなたが同様にシンプルなコードを使用する可能性があります仕様の一部だ場合 - moresetsを忘れて、そして:
L = len(manysets)
for i xrange(L):
s = manysets[i]
for j in range(i+1, L):
yield i, j, s & manysets[z]
この時間は、あなただけのさまざまな、代わりに「0から数える」にしたいと仮定し; - )
これを試してください:
_lists = [[1, 2, 3, 7], [1, 3], [1, 2, 3], [1, 3, 4, 7]]
_sets = map( set, _lists )
_intersection = reduce( set.intersection, _sets )
とインデックスを取得します:
_idxs = [ map(_i.index, _intersection ) for _i in _lists ]
乾杯、
ホセ・マリア・ガルシア
PS:私は質問を誤解し申し訳ありません。