Как исправить этот код в подсчете дубликатов на строку с несколькими столбцами? - PullRequest
0 голосов
/ 19 июня 2019

Нужна помощь, чтобы исправить этот код, который я пробовал, чтобы подсчитать дубликаты для нескольких строк и столбцов в текущей строке.

Это самое простое, что я могу придумать

Table.AddColumn(Source, "Add",
each List.Count(
Table.SelectRows(
    Source,
    (C) => List.Intersect(Table.ToList(Source),C(Table.ToList(Source)))=5
)[Column1]
))

Этоимеет следующую ошибку -

Expression.Error: We cannot convert a value of type Record to type Function.
Details:
    Value=Record
    Type=Type

Вот примерные данные:

+---------+---------+---------+---------+---------+---------+----------------+--------------------+
| Column1 | Column2 | Column3 | Column4 | Column5 | Column6 | Count of Dup 5 | Comments           |
+---------+---------+---------+---------+---------+---------+----------------+--------------------+
|       1 |      12 |      17 |      25 |      27 |      39 |              2 | -row line 1 and 2  |
|       1 |      12 |      17 |      25 |      27 |      44 |              2 | -row line 1 and 2  |
|      98 |      99 |     100 |     101 |     102 |     103 |              1 | -only current line |
+---------+---------+---------+---------+---------+---------+----------------+--------------------+

1 Ответ

1 голос
/ 19 июня 2019

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
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...