Страницы: 1
RSS
Нечёткий текстовый поиск в одной колонке
 
Добрый день.
Интересует такой вопрос как можно реализовать поиск дублей в одной колонке если наименования могут быть нечёткими.
---
God of war III PS4
God of war 3 PS4
Фигурка God of war
аккумулятор Xiaomi
god of war 3 (бог войны 3) PS4
Дрель шуруповерт E106 black
Шуруповерт E106 black
колекционная фигурка Fuffy POP
фигрука Fuffy POP!
God of war 3 Xbox Oen
 
Интересует так же что из всего написанного считать дублями, а что нет и почему именно так. Но предвидя что-то вроде "все, что содержит фигурка, God of war и Шуруповерт" отвечу: очень плохая идея искать такие дубли, т.к. Excel не умеет различать настолько правильно все возможные варианты и даже если написать код, который будет делать что-то подобное, то процент ошибок будет непозволительно велик.
Даже самый простой вопрос можно превратить в огромную проблему. Достаточно не уметь формулировать вопросы...
 
До этого работал с надстройкой Fuzzy Lookup, но она сравнивает 2 списка и находит более менее похожие значения.
Там тоже бывает много ошибок что в конечном итоге приходится разбирать руками.
---
Меня не интересует прям 100% точный результат. Подойдет и более приближенные совпадения.
Если макрос сможет из 5000 товаров найти 500 близко похожие значения из которых всего 100 будут реально дублями, уже есть хорошо)
 
Вы попробуйте на бумаге описать, почему первая пара это дубли, а вторая нет. И полюбуйтесь простыней, которую нужно засунуть в код. А это всего две пары.

God of war 3 PS4
God of war фигурка

God of war фигурка
колекционная фигурка Fuffy POP
 
Цитата
DartoArem написал:
работал с надстройкой Fuzzy Lookup, но она сравнивает 2 списка и находит более менее похожие значения
лучше этой надстройки вряд ли что-то получится. Поэтому я бы на Вашем месте не сильно надеялся на решение задачи.
Даже самый простой вопрос можно превратить в огромную проблему. Достаточно не уметь формулировать вопросы...
 
Или может кто знает как сделать что бы Fuzzy Lookup искал дубли внутри одной колонки и выводил список
 
DartoArem, вчера Jack Famous создал ТЕМУ. У него там много полезных ссылок на подобные решения, может пригодится.
Ну если там ничего не найдете подходящего, то вот написал на скорую руку. Только есть недостаток, долго работает.
И ещё если подойдет, то перед началом, желательно удалить знаки пунктуации, скобки, двойные пробелы и т.п. Хотя там это все делается, но с заменой на пробел, поэтому для нормального разбития желательно проконтролировать.
Изменено: msi2102 - 18.12.2019 11:45:58
 
Цитата
DartoArem написал:
искал дубли внутри одной колонки и выводил список
Сделать дубль списка)
 
Доброе время суток.
Вариант. Сам не понял как работает. Но по представленному примеру где-то что-то группирует :) Хотя, конечно, лучше через декартово произведение с фильтром идти, но будет, мягко говоря, медленно.
 
Как вариант
 
Prosvetov, только где взять этот Table.FuzzyNestedJoin
 
artyrH, PBI, он бесплатный.
Или подписывайтесь на О365 с января 2020 по идее во всех планах обновлений он появится, как и многие другие вкусности в PQ.
Вот горшок пустой, он предмет простой...
 
Prosvetov, в вашем файле отсутствует запрос sentence.1
 
Цитата
PooHkrd написал:
на О365 с января 2020
уже есть
 
Андрей VG, где-нибудь есть внятный разбор механики работы кастомного сравнивателя для Table.Group? У Имке Фельдман видел только пример применения, но без погружения в пучины. Очень хочется разобраться. Тем более что там ведь сравнивалка должна отличаться для Local и Global вариантов или от этого параметра только зависит количество переборов до останова набора строк в отдельную группу?
Вот горшок пустой, он предмет простой...
 
Цитата
PooHkrd написал:
подписывайтесь на О365
для подписки необходимо ввести данные банковской карты. мне такой вариант не подходит.
 
Prosvetov, зависит от плана обновлений, не у всех есть. Так чтобы прямо у всех владельцев О365 появилось это будет именно с 01.2020.
Вот горшок пустой, он предмет простой...
 
artyrH,  :D  
Цитата
необходимо ввести данные банковской карты
Изменено: Mershik - 19.12.2019 11:14:10
Не бойтесь совершенства. Вам его не достичь.
 
Цитата
PooHkrd написал:
где-нибудь есть внятный разбор механики работы кастомного сравнивателя для Table.Group?
Не встречал, но можно по исследовать. Вечером попробую.
Цитата
PooHkrd написал:
Тем более что там ведь сравнивалка должна отличаться для Local и Global
Для Local - там всё понятно. Результат 0 - член текущей локальной группы, не 0 - новая текущая локальная группа при последовательном просмотре.
 
Андрей VG, т.е. я правильно понимаю, что при Локльной группировке алгоритм за один проход последовательных сравнений строк формирует результат, а при глобальной он сначала для первой строки перебирает все остальные, выделяет это в отдельную группу, потом для оставшихся строк начинает перебор по тому же алгоритму.
И именно на этом основывается лайфхак от Имке, что сортировка + локальная группировка на большом массиве в разы производительнее чем просто глобальная группировка на неупорядоченном массиве, при этом результат идентичный. Сам пробовал получается сильно шустрее.
Вот горшок пустой, он предмет простой...
 
Цитата
PooHkrd написал:
И именно на этом основывается лайфхак от Имке, что сортировка + локальная группировка на большом массиве в разы производительнее чем просто глобальная
Как-то не сходится. Таблица: поле f1 создано формулой =СЛУЧМЕЖДУ(1;999999), поле v - формулой =СЛЧИС(). Всего более миллиона строк. Уникальных значений по f1 при группировке по f1 и сумме по v около 650000 строк.
Код обычной группировки
Код
let
    Source = Excel.CurrentWorkbook(){[Name="Таблица1"]}[Content],
    #"Changed Type" = Table.TransformColumnTypes(Source,{{"f1", Int64.Type}, {"v", type number}}),
    #"Grouped Rows" = Table.Group(#"Changed Type", {"f1"}, {{"sum", each List.Sum([v]), type number}})
in
    #"Grouped Rows"
выполнился за 12 секунд

Код с лайфхак
Код
let
    Source = Excel.CurrentWorkbook(){[Name="Таблица1"]}[Content],
    #"Changed Type" = Table.TransformColumnTypes(Source,{{"f1", Int64.Type}, {"v", type number}}),
    sorted = Table.Sort(#"Changed Type", "f1"),
    #"Grouped Rows" = Table.Group(sorted, {"f1"}, {{"sum", each List.Sum([v]), type number}}, GroupKind.Local)
in
    #"Grouped Rows"

за 23 секунды. Тогда вопрос - в каком контексте лайфак будет быстрее?
 
Андрей VG, У меня был вариант когда на массиве 10кк строк группировался по 5 полям, в общей сложности там было порядка 100к уникальных групп. Вариант с обычной группировкой уходил в задумчивость и в себя не возвращался. Вариант от Имке отрабатывает за 10-15 минут в зависимости от загруженности сервака.
Изменено: PooHkrd - 20.12.2019 18:06:35
Вот горшок пустой, он предмет простой...
 
Цитата
PooHkrd написал:
Вариант от Имке отрабатывает за 10-15 минут
Да, что-то намутили мелкомягкие. На девяти столбцах группировки f1-f9, созданных формулой =ТЕКСТ(СЛУЧМЕЖДУ(1;10);"0000000000000000"), и v - формулой =СЛЧИС(), получилось для миллиона строк входа и миллиона строк вывода по алгоритму лайфхака
Код
let
    groupNames = List.Transform({"1".."9"}, each "f" & _),
    groupSort = List.Transform(groupNames, each {_, Order.Ascending}),
    Source = Excel.CurrentWorkbook(){[Name="Таблица1"]}[Content],
    #"Changed Type" = Table.TransformColumnTypes(Source,{{"f1", type text}, {"f2", type text}, {"f3", type text}, {"f4", type text}, {"f5", type text}, {"f6", type text}, {"f7", type text}, {"f8", type text}, {"f9", type text}, {"v", type number}}),
    sorted = Table.Sort(#"Changed Type", groupSort),
    result = Table.Group(sorted, groupNames, {{"sum", each List.Sum([v]), Number.Type}}, GroupKind.Local)
in
    result
время выполнения 437 секунд.
Но, можно и ускорить. Такой подход
Код
let
    groupNames = List.Transform({"1".."9"}, each "f" & _),
    Source = Excel.CurrentWorkbook(){[Name="Таблица1"]}[Content],
    #"Changed Type" = Table.TransformColumnTypes(Source,{{"f1", type text}, {"f2", type text}, {"f3", type text}, {"f4", type text}, {"f5", type text}, {"f6", type text}, {"f7", type text}, {"f8", type text}, {"f9", type text}, {"v", type number}}),
    groupTypes = List.Transform(groupNames, each {_, Type.TableColumn(Value.Type(#"Changed Type"), _)}),
    addGroupList = Table.AddColumn(#"Changed Type", "group", each Record.FieldValues(Record.SelectFields(_, groupNames))),
    result = Table.Group(addGroupList, {"group"}, {{"sum", each List.Sum([v]), Number.Type}}),
    listToTable = Table.TransformColumns(result, {"group", each Table.FromRows({_}, groupNames)}),
    expanded = Table.ExpandTableColumn(listToTable, "group", groupNames),
    return = Table.TransformColumnTypes(expanded, groupTypes)
in
    return
отработал за 93 секунды
 
Андрей VG, спасибо, интересный вариант. А почему именно список? В запись собирать и по ней группироваться пробовали?
На днях по гоняю его на своем массиве - отпишусь. Ранее я сцеплял в текст поля и группировался по тексту, потом расцеплял. Такой вариант отрабатывал примерно за те же 10-15 минут. Но тут надо понимать что 10-15 минут это не чисто группировка, а все преобразования в запросе включая чтение с 800 Гб xlsx файлов.
Кстати, перевыгрузка массива в txt не дала каких-то колоссальных результатов, но на 1 - 1.5 минуты стало работать быстрее. Я ждал от этого большего. С другой стороны, если на xlsx нет-нет да и подвиснет (хоть и редко, но приятного мало), с текстовыми выгрузками не было ни одного сбоя - работает как часы.
Вот горшок пустой, он предмет простой...
Страницы: 1
Наверх