1

私は Hadoop ストリーミング ジョブとして Python スクリプトを実行していますが、この記事は Hadoop に関する知識よりも、いくつかのコア Python コンセプトに関連しています。

基本的に、重複を見つけたい一連の行があります

$ cat sample.txt
ID1    2143,2154,
ID2    2913,14545
ID3    2143,2390,3350,5239,6250
ID4    2143,2154,2163,3340
ID5    2143,2154,2156,2163,3340,3711

最後に、重複するレコードのペアを見つけて数えたいと思います。たとえば、次のようになります。

2143,2154    3
2143,2163    2
2143,3340    2
2154,2163    2
2154,3340    2
2163,3340    2

これを行う方法は、Python で記述された Hadoop ストリーミング ジョブを作成することです。このジョブでは、マッパーは基本的に、指定された行のすべてのペアの組み合わせを出力し、レデューサーによってさらに処理されます。

私の質問は実際には非常に単純です.Pythonで特定の行のすべてのペアの組み合わせを効率的に生成するにはどうすればよいですか? 私の場合、ペア (x,y) はペア (y,x) と同じであることに注意してください。たとえばID3、マッパーで生成された次のリストが必要です。

[(2143,2390), (2143,2390), (2143,3350), (2143,5239), (2143,6250), (2390,3350), (2390,5239), (2390,6250), (3350,5239), (3350,6250), (5239,6250)]

私は確かに for ループの束でこれを行うことができますが、それはかなり醜いです. itertools を使用してみましたが、適切に何かを取得できませんでした。何かご意見は?

4

3 に答える 3

8

どうですか:

x = [2143, 2390, 3350, 5239, 6250]
itertools.combinations(x, 2)

与える:

(2143, 2390) (2143, 3350) (2143, 5239) (2143, 6250) (2390, 3350) (2390, 5239) (2390, 6250) (3350, 5239) (3350, 6250) (5239, 6250)
于 2012-05-14T20:05:13.393 に答える
2

些細なことで何が悪い

for i, x in enumerate(L):
    for y in L[i+1:]:
        whatever(x, y)

?

whateverこれは、要素の各ペアを個別に渡すことを呼び出しますL(個別とは、個別のインデックスを意味しますL。重複が含まれている場合、それらは等しい可能性があります)。

于 2012-05-14T20:08:43.610 に答える
2

l問題のリストである場合

[(x, y) for x in l for y in l if x < y]

または、ジェネレーターを作成することもできます。

def pairs(l):
  for x in l:
    for y in l:
      if x < y:
        yield x, y

これには、すべてのペアを同時にメモリに保持する必要なく、「その場で」ペアを生成できるという利点があります。

を使用して同様のことを実現できますがitertools.product(l, l)、これは両方を生成し(x, y) and (y, x)、 のようなペアも生成し(x, x)ます。それらを除外するには、次のようにする必要があります。

itertools.ifilter(lambda (x,y): x < y, itertools.product(l,l))
于 2012-05-14T19:58:01.137 に答える