Как указать формат даты и времени в C# Deedle при чтении и записи CSV? - PullRequest
1 голос
/ 16 апреля 2020

Предполагая, что у меня есть следующий файл data.csv.

Timestamp,DoubleCol,BooleanCol,StringCol
04/15/2020 06:45:02.085-07:00,1.52,True,Some String
04/15/2020 06:45:03.057-07:00,2.32,False,Some String
04/15/2020 06:45:04.058-07:00,4.55,True,Some String
04/15/2020 06:45:05.057-07:00,1.52,False,Some String
04/15/2020 06:45:06.057-07:00,2.32,True,Some String
04/15/2020 06:45:07.057-07:00,4.55,False,Some String
04/15/2020 06:45:08.057-07:00,1.52,True,Some String
04/15/2020 06:45:09.058-07:00,2.32,False,Some String
04/15/2020 06:45:10.057-07:00,4.55,True,Some String
04/15/2020 06:45:11.057-07:00,1.02,False,Some String

Мне нужно прочитать этот CSV в кадр, выполнить некоторую фильтрацию в столбце Timestamp, а затем записать CSV, но со столбцом Timestamp как строка ISO 8601.

Если я просто сделаю это, первый столбец будет иметь тип String, а не DateTimeOffset.

filePath = "data.csv";
timestampFormat = "MM/dd/yyyy HH:mm:ss:fffK"; // This is sent along with the CSV file.
var frame = Frame.ReadCsv(filePath);

Также, если я попробую это:

var tsFrame = frame.IndexRows<DateTime>("Timestamp");

Я получаю

FormatException: String '04/15/2020 06:45:02.085-07:00' was not recognized as a valid DateTime.

Итак, как я могу указать формат DateTime для использования при разборе первого столбца?

И затем, как я могу указать использование ISO 8601 при записи CSV out?

NOTE

Это упрощенный сценарий. На самом деле, я не знаю схему заранее. За исключением того, что первый столбец является меткой времени (для которой я также получаю формат). Остальные столбцы могут быть чем угодно. Поэтому мне нужно решение, которое не зависит от схемы времени компиляции.

Ответы [ 2 ]

2 голосов
/ 16 апреля 2020

Во-первых, ваш формат метки времени неверен. У вас есть формат "MM/dd/yyyy HH:mm:ss:fffK" с : перед fffK, но ваши данные выборки имеют . до миллисекунд, т.е. 04/15/2020 06:45:10.057-07:00.

Теперь нет простого способа указать точную дату формат анализа времени при вызове ReadCsv, но вы можете использовать операцию Select и ReplaceColumn, чтобы прочитать данные как string, а затем явно проанализировать даты:

df.ReplaceColumn("Timestamp",
  df.GetColumn<string>("Timestamp").Select(kvp => 
    DateTime.ParseExact(kvp.Value, timestampFormat, 
      CultureInfo.InvariantCulture, DateTimeStyles.None)));
0 голосов
/ 16 апреля 2020

Я не знаком с Deedle, но вы можете попробовать использовать мою библиотеку Sylvan.Data.Csv (доступна как пакет nuget ), которая позволяет читать данные CSV со схемой. Если посмотреть на API-интерфейс Deedle: Frame также имеет метод ReadReader, который позволяет обеспечить IDataReader, поэтому моя библиотека должна легко интегрироваться.

using var tr = File.OpenText("data.csv");

var schema = new TypedCsvSchema();
schema.Add(0, typeof(DateTime));
schema.Add(1, typeof(double));
schema.Add(2, typeof(bool));
schema.Add(3, typeof(string));

var options = new CsvDataReaderOptions { Schema = schema };
DbDataReader dr = CsvDataReader.Create(tr, options);


var frame = Frame.ReadReader(dr);
...