0

次の形式の10GBのデータがあります。

A=good
B=c++

今、私はBを見つけたいと思います。たとえば、「c ++」を見つけたいと思います。この場合、この問題に対して私が従うアプローチは、B部分(つまり、最初の2行目)を選択し、そこから等しい文字列を見つけることです。 Bの文字列に。次に、ループの2番目のラウンドで..Bの別の値(現在は4行目)を探しており、そこから等しい文字列を持つBを見つけます....など

ただし、上記のアプローチには多くの時間がかかります。この問題を効率的に解決するためのPythonの他のアプローチはありますか。

4

4 に答える 4

8

ファイルが大きすぎてメモリに簡単に収まらないため、次のようにします。

  1. As と Bs の 2 つのファイルに分割
  2. それぞれを並べ替える (例: unixsortまたは Python の外部メモリ マージソートを使用)
  3. マージソートのマージ手順を実行して、重複を見つけます
于 2012-06-15T16:18:57.200 に答える
2

これを行う最善の方法は、データを読み取り、アイテムのセットとAアイテムのセットを構築することBです。次に、2つの交差点を見つけるだけです。

唯一の潜在的な欠点は、一度にすべてのデータをメモリに収める必要があることです。大規模なデータセットを考えると、これは問題になる可能性があります。半分を処理できる場合は、アイテムのセットを作成し、セットAに対してBチェックするアイテムを処理できます。

例:

入力データの使用:

A=good
B=c++
A=df
B=kj
A=c++
B=programming language

最初の方法は、次のように簡単に実行できます。

a = set()
b = set()
with open("test") as data:
    for line in data:
        line_data = line[2:].strip()
        if line.startswith("A"):
            a.add(line_data)
        else:
            b.add(line_data)

print(a & b)

私たちに与えること:

{'c++'}

2 番目の方法は次のように実行できます。

with open("test") as data:
    a = {line[2:].strip() for line in data if line.startswith("A")}

with open("test") as data:
    results = {item for item in (line[2:].strip() for line in data if line.startswith("B")) if item in a}

print(results)

これは同じ結果をもたらしますが、データの半分をメモリに格納するだけで (データの重複が大きい​​場合はそれ以下)、セット ルックアップの効率的な性質によりさらに効率的です。

于 2012-06-15T16:15:59.497 に答える
0

これを実行します:

cat huge_file | awk 'BEGIN {FS = "="} { print $2 "***" $1 }' | sort -n | awk 'BEGIN {FS = "\\*\\*\\*"} { if (prev == $1 && $2 == "B") { print $1 } prev = $1 }'

これにより、それらが A/B と値に分割され、値で並べ替えられ、隣接するペアが検出されます。部分文字列「 * 」を含む文字列はないと仮定しますが、表示されないことがわかっている他の部分文字列に置き換えることができます。

于 2012-06-15T16:46:22.220 に答える