0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 3 years have passed since last update.

C# CSVファイルの数値データをDoubleのジャグ配列として得る

Last updated at Posted at 2021-04-26

C#で、ヘッダー行があり、その下に数値データが並んでいるCSVファイルを一括して取り込む。
ヘッダー(複数行可)はStringのジャグ配列に、数値データは、列ごとにDoubleのジャグ配列に入れる。

開発環境

Visual Studio 2019
Windows 10
C#
.net 5

ファイル 先頭から指定行スキップして、指定行数取り込み

もしかしたら.toArray()しないほうが、速度、メモリ的に有利なのかもしれないけど、扱いが楽なのでArray化

string CsvFilePath = "test.csv";
int RowsToSkip = 2;
int Rows = 1000;
string[] Lines = System.IO.File.ReadLines(CsvFilePath)
                                 .Skip(RowsToSkip).Take(Rows).ToArray();

CSV文字列一行を、double配列にする

double[] CsvString.Split(',')
          .Select(n => double.TryParse(n.Trim(), out double result) ? result : 0)
          .ToArray();

コード一式

/// <summary>
/// CSV文字列一行を、double配列にする
/// </summary>
/// <param name="CsvString"></param>
/// <returns></returns>
private double[] CsvStringToDoubleArray(string CsvString)
{
    return CsvString.Split(',').Select(n => double.TryParse(n.Trim(), out double result) ? result : 0).ToArray();
}
/// <summary>
/// CSVファイルからデータ読み込み 
/// ヘッダー列と数値データ配列を得る
/// </summary>
/// <param name="CsvFilePath">CSVファイルパス</param>
/// <param name="RowsToSkip">読み込みから飛ばす行数</param>
/// <param name="HeaderRows">ヘッダー行数</param>
/// <param name="HeaderEncode">ヘッダー文字のエンコード</param>
/// <param name="FixedDataRows">読み込みサイズ データがこれ以下しかない場合0で埋められる</param>
/// <returns></returns
public (string[][] Header, double[][] NumericData) CSVtoDoubleArray
                        (string CsvFilePath, int RowsToSkip = 0, int HeaderRows = 1, string HeaderEncode = "Shift_JIS",int FixedDataRows = 0)
{

    //.net 5以降これがないとShift_JISエンコードが読み込まれない
    Encoding.RegisterProvider(CodePagesEncodingProvider.Instance);
    string[] Lines;
    try
    {
        //FixedDataRowsが設定されていなかったら、全行、設定されていた、その行数分取得
        if (FixedDataRows == 0)
            Lines = System.IO.File.ReadLines(CsvFilePath, Encoding.GetEncoding(HeaderEncode)).Skip(RowsToSkip).ToArray();
        else
            Lines = System.IO.File.ReadLines
                (CsvFilePath, Encoding.GetEncoding(HeaderEncode)).Skip(RowsToSkip).Take(HeaderRows + FixedDataRows).ToArray();
    }
    catch (Exception e)
    {
        MessageBox.Show(e.Message);
        return (null, null);
    }
    int DataRows = Lines.Length- HeaderRows;

    //データ列が0以下なら戻す
    if (DataRows <= 0)
        return (null, null);

    string[][] Header = new string[HeaderRows][];

    //ヘッダー行数分読み込み
    for (int i = 0; i < HeaderRows && i < Lines.Length; i++)
        Header[i] = Lines[i].Split(',').Where(x => x != "").Select(x => x.Trim('\"')).ToArray(); //空白列は除外 注 行最後の,を想定 途中に,,があるとずれる

    int DataColumns;
    //ヘッダーがあれば、先頭ヘッダーの列数 なければ先頭データの列数
    if (HeaderRows > 0)
        DataColumns = Header[0].Length;
    else
        DataColumns = CsvStringToDoubleArray(Lines[0]).Length;

    //データ配列確保用行数
    int AllocationDataRows = DataRows;
    if (FixedDataRows != 0)
        AllocationDataRows = FixedDataRows;

    //ヘッダー、指定行数のジャグ配列の領域確保
    double[][] NumericData = new double[DataColumns][];
    for (int Col = 0; Col < DataColumns; Col++)
        NumericData[Col] = new double[AllocationDataRows];

    for (int Row = 0; Row < DataRows && Row < FixedDataRows; Row++)
    {
        var line = CsvStringToDoubleArray(Lines[Row + HeaderRows]);
        for (int Col = 0; Col < DataColumns && Col < line.Length; Col++)
            NumericData[Col][Row] = line[Col];
    }
    return (Header, NumericData);
}

呼び出し例

var CsvFilePath = "Test.csv";

//6000行読み込み
(string[][] Header, double[][] Data) = CSVtoDoubleArray(CsvFilePath,RowsToSkip:4,FixedDataRows:6000);

Header[0] ヘッダー一行目のstring配列
Header[0][0] ヘッダー一行目、1列目

Data[0] データ一列目のdouble配列
Data[0][0] データ一列目の一つ目のデータ

0
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?