3

我正在做一个小项目,我需要一些帮助。我有一个包含 150,000 行的 CSV 文件(每行有 10 列数据)。我正在使用 fscvread 读取文件,并且在循环期间,我想将每行的其中一列(称为 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 大约需要 60 秒来遍历 200 行数据,方法 2 可以在 60 秒内循环 500 行。

有一个更好的方法吗?

再一次,我正在寻找一种有效的方法来(基本上)array_diff 一个包含 10,000 个单词的数组,一次针对 150,000 个字符串。

非常感谢您的帮助。

4

6 回答 6

2

以下只是一个替代方案。它可能会也可能不会满足您的要求。

它在我的笔记本电脑上使用 10k 单词字典和 15k 字符串执行 84 次操作/秒。

缺点是它不会删除单词周围的空格。

$wordlist 只是每行一个单词,可以是一个文件。

$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);
}

另一个执行速度更快的示例(107ops/s,15kb 字符串和 10k 单词字典)

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

您的 10000 字数组是否已排序?如果没有,请尝试先对其进行排序。

编辑:好的,因为它已排序,我猜也许 PHP 的 array_search 不进行二进制搜索,所以我会寻找二进制搜索实现并使用它。如果确实它只是一个线性搜索,那么您将通过这种方式获得一个数量级的速度提升。

于 2011-03-24T14:38:09.467 回答
1

PHP 不是速度的语言,但我想你知道这一点。我必须在我正在编写的项目中做类似的事情,我正在用 PHP 编写一个文件,然后使用独立的 Matlab 读取该文件,处理它并将其输出另一个。

你也可以这样做,用 C 语言编写一个与array_diff(). 我认为会有很大的不同,尽管我没有做过任何测试。

于 2011-03-24T14:39:43.333 回答
1

不爆炸 stringx 并为 $array_10000 中的每个单词做一个stripos()怎么样?

像这样:

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

我没有测试过这个,但它只是发生在我身上:

您可以尝试使用正则表达式预先解析文件以获得要过滤的 150,000 个单词(基于列分隔符),然后您可以进行文本替换,根据我搜索的这篇文章选择最佳函数。

我希望它有帮助!干杯!

于 2011-03-24T14:48:00.293 回答
0

你可以只做foreachimplode

$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 回答