List.Intersect не очень подходит для подсчета повторяющихся строк, поскольку эта функция будет возвращать только те элементы, которые являются общими для всех из сравниваемых списков, и будет возвращать толькоэти элементы один раз.
Все три параметра, приведенные ниже, в основном одинаковы, только с немного отличающимися подходами.
Мы добавляем вычисляемый столбец, который принимает текущую запись, фильтрует весь набор данных для записей с одинаковымизначений ( Table.SelectRows / List.Select ) и подсчитывает отфильтрованный результат ( Table.RowCount / List.Count .
Поскольку две записи с одинаковыми значениями не обрабатываются как равные, обе записи для сравнения сначала должны быть превращены в списки, либо путем вызова Record.ToList для каждой записи, либо Table.ToRows для всего набора данных.
Опция 1
Превращение каждой строки таблицы в список во время сравнения.
let
Source = Excel.CurrentWorkbook(){[Name="Table1"]}[Content],
Dupes = Table.AddColumn(Source, "Dupes", (CurrentRecord) =>
Table.RowCount(
Table.SelectRows(Source, (CompRecord) =>
Record.ToList(CurrentRecord) = Record.ToList(CompRecord)
)
)
)
in
Dupes
Опция 2
Превращая стол всписок (таблица) списков (записей) перед сравнением.
let
Source = Excel.CurrentWorkbook(){[Name="Table1"]}[Content],
Dupes = Table.AddColumn(Source, "Dupes", (CurrentRecord) =>
List.Count(
List.Select(Table.ToRows(Source), (CompRecordAsList) =>
Record.ToList(CurrentRecord) = CompRecordAsList
)
)
)
in
Dupes
Опция 3
Превращение таблицы в список (таблицу) списков (записей) перед сравнением и использованием переменной дляизбегайте повторных звонков на Record.ToList
.
Я не знаю, сколько стоит Record.ToList
.Для больших наборов данных это может повысить производительность.
let
Source = Excel.CurrentWorkbook(){[Name="Table1"]}[Content],
Dupes = Table.AddColumn(Source, "Dupes", (CurrentRecord) =>
let
CurrentRecordAsList = Record.ToList(CurrentRecord),
ReturnValue = List.Count(
List.Select(Table.ToRows(Source), (CompRecordAsList) =>
CurrentRecordAsList = CompRecordAsList
)
)
in
ReturnValue
)
in
Dupes
Редактировать на основе пояснений в комментариях
Опция 4
Поиск общих значений, независимых от столбцов.
Поскольку вас интересует только подсчет строк, в которых ровно n-m
значения столбцов из n
столбцов равны, мы действительно можем использовать List.Intersect вместо прямого сравнения на равенство.
Ниже приведенооснован на Вариант 3 , но будет работать одинаково во всех трех случаях.Мы заменим CurrentRecordAsList = CompRecordAsList
на вызов List.Intersect
в этих двух списках (где каждый список представляет одну запись, т.е. каждый элемент списка представляет значение в одном из столбцов), посчитаем количество общих элементов и сравним с n-m
(в данном случае 5
).
Осторожно # 1: Элементы, которые при совпадении всех столбцов больше не учитываются, что означает, чтоПолученное число теперь представляет только другие записи.Текущая запись, которая была учтена при сравнении на равенство, не включается.
Сравнение на равенство: 1
означает, что нет дубликатов (только найдено самостоятельно)
Сравнение в секундах: 1
означает одно другое запись была найдена
Осторожно # 2: Это не проверит, что общие значения находятся в одних и тех же столбцах в сравниваемых записях.Только то, что значения встречаются где-то в обеих записях.
let
Source = Excel.CurrentWorkbook(){[Name="Table1"]}[Content],
Dupes = Table.AddColumn(Source, "Dupes", (CurrentRecord) =>
let
CurrentRecordAsList = Record.ToList(CurrentRecord),
ReturnValue = List.Count(
List.Select(Table.ToRows(Source), (CompRecordAsList) =>
List.Count(List.Intersect({CompRecordAsList, CurrentRecordAsList})) = 5
)
)
in
ReturnValue
)
in
Dupes
Опция 5
Если вам также необходимо проверить, что общие значения находятся в одних и тех же столбцах, List.Intersect
больше не помогает.
То, что происходит ниже, следует тому же подходу, что и раньше.Мы добавляем вычисляемый столбец, который принимает текущую запись, фильтрует полный набор данных и считает отфильтрованные записи.Только то, что критерии фильтрации теперь немного сложнее.
Пользовательская функция, используемая для фильтрации набора данных, использует Table.ColumnNames , чтобы получить список имен столбцов, фильтрует этот список ( List.Выберите ) с помощью Record.Field , чтобы сравнить соответствующий столбец обеих записей, подсчитать итоговые общие столбцы ( List.Count ) и сравнить это с порогом n-m
(например, 5
).
let
Source = Excel.CurrentWorkbook(){[Name="Table1"]}[Content],
Dupes = Table.AddColumn(Source, "Dupes", (CurrentRecord) =>
Table.RowCount(
Table.SelectRows(Source, (CompRecord) =>
List.Count(
List.Select(Table.ColumnNames(Source), (ColumnName) =>
Record.Field(CurrentRecord, ColumnName) = Record.Field(CompRecord, ColumnName)
)
) = 5
)
)
)
in
Dupes