3

私は小さなプロジェクトに取り組んでいますが、助けが必要です。150,000行のCSVファイルがあります(各行には10列のデータがあります)。fscvreadを使用してファイルを読み取り、ループ中に各行の列の1つ(stringxと呼びます)を10,000語の配列と照合します。stringxに10,000語のいずれかが存在する場合、preg_replaceを使用して削除されます。

これですべて問題ありません。私はすべてうまく機能していますが、問題は遅すぎることです。

配列を一致させるために2つの方法を試しました。1)explode( ""、$ stringx)を使用してstringxを配列に変換してから、array_diff($ array_stringx、$ array_10000);を使用します。2)$array_10000でforeachを使用し、$stringxでpreg_replaceを使用します

方法1は200行のデータを処理するのに約60秒かかり、方法2は60秒で500行をループできます。

これを行うためのより良い方法はありますか?

繰り返しになりますが、私は(基本的に)10,000語の配列を150,000文字列に対して一度に1つずつarray_diffする効率的な方法を探しています。

ヘルプは大歓迎です。

4

6 に答える 6

2

以下は単なる代替手段です。要件を満たす場合と満たさない場合があります。

私のラップトップでは、10,000 語の辞書と 15,000 の文字列で 84 ops/秒を実行します。

欠点は、単語の周りのスペースが削除されないことです。

$wordlist は、それぞれ 1 つの単語を含む行であり、ファイルである可能性があります。

$dict = array_flip(preg_split('/\n/',$wordlist));

function filter($str,$dict) {
  $words = preg_split('/\s/',$str);
  sort($words);
  $words = array_unique($words);

  foreach ($words as $word) {
    if (key_exists($word,$dict)) {
        $removeWords[] = '/\b' . $word . '\b/';
    }
  }
  return preg_replace($removeWords, '', $str);
}

少し高速に実行される別の例 (15kb の文字列と 10k の単語の辞書で 107ops/s)

function filter2($str,$dict) {
  $words = preg_split('/\b/',$str);
  foreach ($words as $k => $word) {
    if (key_exists($word,$dict)) {
        unset($words[$k]);
    }
  }
  return implode('', $words);
}
于 2011-03-24T15:16:04.310 に答える
1

stringxを分解せず、$ array_10000の各単語に対してstripos()を実行するのはどうですか?

このような:

foreach ($array_10000 as $word)
{
    if (stripos($stringx, $word) !== false)
    {
        // do your stuff
    }
}
于 2011-03-24T14:40:46.803 に答える
1

10000 ワードの配列はソートされていますか? そうでない場合は、まずソートしてみてください。

編集: ソートされているので、PHP の array_search はバイナリ検索を行わないのではないかと推測しているので、バイナリ検索の実装を探して使用します。実際にそれが単なる線形検索である場合、その方法で速度が大幅に向上します。

于 2011-03-24T14:38:09.467 に答える
1

PHP は速度を重視する言語ではありませんが、それはご存じのとおりです。私が書いているプロジェクトでそのようなことをしなければならず、PHPでファイルを書いてから、Matlabスタンドアロンを使用してそのファイルを読み取り、処理し、別のファイルに出力します。

同じことを行って、C で と同じことを行う小さなプログラムを作成することもできますarray_diff()。テストはしていませんが、大きな違いがあると思います。

于 2011-03-24T14:39:43.333 に答える
0

foreachとを実行できますimplode

$words = array("one","two", "three");
$number = 0;
foreach ($words as $false_array)
{
$number += 1;
$array[$number] = $false_array;
echo "Added ". $false_array . ". ";
}
foreach ($words as $false_array)
{
echo "Array Contains " . $false_array . ". ";
}

これを php で実行すると、次のようになります。

Added one. Added two. Added three. Array Contains one. Array Contains two. Array Contains three.
于 2015-07-07T23:19:24.743 に答える
0

私はこれをテストしていませんが、ちょうど私に起こりました:

正規表現を使用してファイルを事前解析して、(列区切りに基づいて) フィルター処理する 150,000 語を取得してから、この記事に基づいて最適な関数を選択してテキスト置換を行うことができます。

それが役立つことを願っています!乾杯!

于 2011-03-24T14:48:00.293 に答える