Сопоставление значений массива со строкой PHP
Я работаю над небольшим проектом, и мне нужна помощь. У меня есть CSV-файл со 150 000 строк (каждая строка содержит 10 cols данных). Я использую fscvread для чтения файла, и во время цикла я хочу сопоставить один из столбцов (назовем его stringx) каждой строки с массивом из 10 000 слов. Если какое-либо из 10 000 слов существует в stringx, оно удаляется с помощью preg_replace.
Теперь все это прекрасно. У меня все работает нормально, но проблема в том, что он слишком медленный.
Я попробовал 2 методы для сопоставления массива.
1) я stringx преобразовать в массив с помощью взорваться(" ", $stringx), а затем использовать array_diff($array_stringx, $array_10000);
2) Используйте foreach на $array_10000 и preg_replace на $stringx
Метод 1 занимает около 60 секунд, чтобы пройти через 200 строк данных, а метод 2 может зациклить 500 строк за 60 секунд.
Есть ли лучший способ сделать это?
Еще раз, я ищу эффективный способ (в основном) array_diff массив из 10 000 слов против 150 000 струны по одной за раз.
Помощь очень ценится.
6 ответов:
Нижеследующее является лишь альтернативой. Он может соответствовать вашим требованиям, а может и не соответствовать.
Он выполняет 84 операции в секунду со словарем 10k слов и строкой 15k на моем ноутбуке.
Недостатком является то, что он не удаляет пробелы вокруг слов.$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 string и 10k words dictionary)
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); }
Как насчет того, чтобы не взрывать stringx, а делать stripos() для каждого слова в $array_10000?
Вот так:
foreach ($array_10000 as $word) { if (stripos($stringx, $word) !== false) { // do your stuff } }
Ваш массив 10000 слов отсортирован? Если нет, попробуйте сначала отсортировать его.
Edit: хорошо, поскольку он отсортирован, я предполагаю, что, возможно, array_search PHP не выполняет двоичный поиск, поэтому я бы искал реализацию двоичного поиска и использовал ее. Если это действительно просто линейный поиск, то вы получите увеличение скорости на порядок.
PHP-это не язык для скорости, но я думаю, вы это знаете. Я должен сделать что-то подобное в проекте, который я пишу, и я пишу файл с PHP, а затем с помощью MATLAB standalone читаю этот файл, обрабатываю его и выводю другой.
Вы можете сделать то же самое и написать небольшую программу на языке Си, которая делает то же самое, что и
array_diff(). Я думаю, что будет огромная разница, хотя я не делал никаких тестов.
Я не проверял это, но это просто произошло со мной:
Вы можете попробовать предварительно разобрать файл с регулярным выражением, чтобы получить 150 000 слов для фильтрации (на основе разделителя столбцов), а затем вы можете сделать замену текста, выбрав лучшую функцию на основе этой статьи, которую я погуглил.
Надеюсь, это поможет! Ура!
Вы можете просто сделать
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.
Comments