如何在C# Deedle中读写CSV时指定日期时间格式?

问题描述 投票:1回答:2

假设我有以下内容 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读到一个Frame中,对时间戳列做一些过滤,然后写一个CSV,但时间戳列是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格式?

然后,我如何在写入CSV时指定使用ISO 8601?

注意

这是一个简化的方案。在现实中,我事先并不知道模式。除了第一列是时间戳(我也收到格式)。其余的列可以是任何东西。所以我需要一个不依赖编译时模式的解决方案。

c# csv datetime datetime-format deedle
2个回答
2
投票

首先,你的时间戳格式不正确。你的格式是 "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
投票

我对Deedle不熟悉,但你可以试试用我的库。Sylvan.Data.Csv(可作为 套餐),可以读取带有模式的CSV数据。看着Deedle API。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);
© www.soinside.com 2019 - 2024. All rights reserved.