【C#】CSVファイルを読み込んでGroupByで加工して出力

C#でCSVを読み込んで、データを加工する方法をまとめます。

特定の列データでグループ化して平均値を求める…などのやり方になります。

CSVを読み込む準備

この記事では下記のCSVを例に使っていきます

CSVを読み込むにはCsvHelperを利用します。

こちらの記事で使い方などを書いています。

csvhelper-eyecatch
【C#】CsvHelper の使い方
利用準備

パッケージのインストール

PM> Install-Package CsvHelper

https:/…

パッケージのインストール

PM> Install-Package CsvHelper

CSVを読み込み、加工して別ファイルに出力

①CsvHelperを使ってCSVを指定したパスから読み込み、ユーザ定義クラスにマッピングを行います。

⓶その後、LinqのGroupByでキーを指定して、平均値と合計値をSelectで射影します。

③最後にCSVを指定したパスに出力します。

using ConsoleApp4;
using CsvHelper;
using System.Globalization;
using System.Text;

var orgFileParh = @"C:testinputorg.csv";
var outPutDirectory = @"C:testoutput";

// .NET 6 の場合でShift-jisをエンコードする場合は下記の処理が必要
Encoding.RegisterProvider(CodePagesEncodingProvider.Instance);

using (StreamReader reader = new(orgFileParh, Encoding.GetEncoding("shift-jis")))
{
    using (CsvReader csvReader = new(reader, new CultureInfo("ja-jp", false)))
    {
        // ①マッピング
        var rows = csvReader.GetRecords<Person>();
        
       // ⓶Teamごとの平均を求める
        var groups = rows.GroupBy(x => x.Team)
                          .Select(x => new 
                          {
                              Team = x.Key,
                              Average = x.Average(a => a.ForAverage),
                              Sum = x.Sum(a => a.ForSum),
                          });

        // ③新しいファイルに出力
        var outputFilePath = $"{outPutDirectory}output.csv";
        using (StreamWriter writer = new(outputFilePath, false, Encoding.GetEncoding("shift-jis")))
        {
            using (CsvWriter csvWriter = new(writer, new CultureInfo("ja-jp", false)))
            {
                csvWriter.WriteRecords(groups);
            }
        }
    }
}

出力されたCSVファイルを開いてみると、Teamごとに平均値と合計値がグループ化されて出力されていることが確認できました。

複数のキーを指定したい場合

GroupByのキーを複数指定したい場合は書き方が少し変わります。

// 複数のキーを指定する場合
var groupsMultiKey = rows.GroupBy(x => new { x.Team, x.Gender })
                  .Select(x => new
                  {
                      Team = x.Key.Team,
                      Gender = x.Key.Gender,
                      Average = x.Average(a => a.ForAverage),
                      Sum = x.Sum(a => a.ForSum),
                  });

Leave a Reply

Your email address will not be published. Required fields are marked *