C # использует эквивалент pandas df.drop_duplicates?

#c# #csv #duplicates #deedle

#c# #csv #дубликаты #файл

Вопрос:

В Python pandas я могу легко удалять дубликаты во фрейме данных с помощью:

 df1.drop_duplicates(['Service Date', 'Customer Number'], inplace=True)
  

Есть ли что-нибудь в C # или Deedle , что было бы таким простым и быстрым? Или мне нужно выполнить итерацию по всему фрейму (из большого файла CSV), чтобы удалить дубликаты?

Данные, с которыми я работаю, импортированы из большого CSV-файла, содержащего около 40 столбцов и 12 тысяч строк. Для каждой даты существует несколько записей для номера клиента. Мне нужно исключить повторяющиеся строки номеров клиентов (оставив только одну уникальную) на дату.

Вот некоторые упрощенные данные, использующие DATE и RECN в качестве столбцов, используемых для удаления дубликатов:

 NAME,       TYPE,  DATE,      RECN,  COMM
Kermit,     Frog,  06/30/14,  1,     1test
Kermit,     Frog,  06/30/14,  1,     2test
Ms. Piggy,  Pig,   07/01/14,  2,     1test
Fozzy,      Bear,  06/29/14,  3,     1test
Kermit,     Frog,  07/02/14,  1,     3test
Kermit,     Frog,  07/02/14,  1,     4test
Kermit,     Frog,  07/02/14,  1,     5test
Ms. Piggy,  Pig,   07/02/14,  2,     3test
Fozzy,      Bear,  07/02/14,  3,     2test
Ms. Piggy,  Pig,   07/02/14,  2,     2test
  

Комментарии:

1. вам также нужна сортировка?

2. Добавлены некоторые упрощенные данные. На самом деле это уже отсортировано как есть, в реальных данных, не помешало бы отсортировать (тестовые данные выше не отсортированы).

Ответ №1:

У Deedle, похоже, нет такой утилиты в его функциях чтения CSV. Использование другого средства чтения CSV для загрузки данных (LumenWorks CSV Reader) Я смог удалить дублирование данных, используя эти методы расширения:

 public static class DeduplicateCsv
{
    public static IEnumerable<Series<string, object>> ReadCsv(this string file)
    {
        // NuGet: PM> Install-Package LumenWorksCsvReader
        using (var csv = new CsvReader(new StreamReader(file), true))
        {
            int fieldCount = csv.FieldCount;

            string[] headers = csv.GetFieldHeaders();
            while (csv.ReadNextRecord())
            {
                var seriesBuilder = new SeriesBuilder<string>();
                for (int i = 0; i < fieldCount; i  )
                {
                    seriesBuilder.Add(headers[i], csv[i]);
                }
                yield return seriesBuilder.Series;
            }
        }
    }

    public static IEnumerable<TSource> DistinctObject<TSource, TCompare>(this IEnumerable<TSource> source, Func<TSource, TCompare> compare)
    {
        var set = new HashSet<TCompare>();
        return source.Where(element => set.Add(compare(element)));
    }

    public static IEnumerable<Series<string, object>> DeDupify(this IEnumerable<Series<string, object>> source, string key)
    {
        return source.DistinctObject(s => s.Get(key));
    }
}
  

Вот как я это использовал:

 var frame = Frame.FromRows("data.csv"
    .ReadCsv()
    .DeDupify("Service Date")
    .DeDupify("Customer Number")
    .ToList()
    );
frame.Print();
  

Обратите внимание, что мне пришлось поставить .ToList() в конце, поскольку Deedle, похоже, работает над IEnumerable более одного раза.