【図で解説】C#でDataTable を Pivot (縦横変換)するには?

当ページのリンクには広告が含まれています。

データベースやCSVファイルなど、一覧形式のデータを保持するのによく使われるDataTableですが、Pivot(縦横変換)しようとした場合、Excelの様な便利な機能が用意されていません。

データ集計やデータ分析では縦持ちのデータを横持に並べ替えることが多いので、メソッドを作ってみました。
もしDataTableをPivotしたくなったら、是非この記事を参考にして下さい。

目次

Pivotの変換イメージ

下記はサンプルプログラムを使った元データとPivotの比較画面です。
ランダムなテストデータを生成したので、売上年月日で並んでいませんが、逆に上から順番に縦横変換されていることが分かるかと思います。

今回は Pivot という名前でメソッドを作成しています。
まずはPivotの引数が縦横変換する上でどのような役割があるのかを確認しておきます。

dataTable変換元のDataTable
ヘッダカラムPivotの左に転記したいカラム名をカンマ区切りで記述
例:"住所,氏名,年齢"
ヘッダカラムが必要ない場合は "" を指定する。
ヘッダカラムが複数あり、任意の位置にY軸カラムを入れたい場合は、その位置にY軸カラムを
記述する。
Y軸カラムY軸に展開したいカラムを1つだけ記述
X軸カラムX軸に展開したいカラムを1つ記述。
カンマ区切りで複数指定すると、それらがアンダースコアで結合されるた結果がカラム名となる。
例: "担当者,地域" と記述した場合、担当者に”山田"、地域に”大阪”が格納されていると、
"山田_大阪" でカラム名が作られる
値カラムY軸とX軸でPivotする際に展開したい値が登録されているカラムを1つだけ記述
戻り値PivotされたDataTable

処理手順

処理手順は次の通りです。今回はPivotという名前でメソッドを作成しました。

基本的な考え方は、元のDataTableからDataRowを取得するループを作り、空のDataTableに対してY軸カラムとX軸カラムを随時追加しながら、Y軸とX軸で特定されるセルに値カラムの内容を書き込んでいくというものです。

  • 結果を格納するために空のDataTable(resultDataTable)を作成
  • ヘッダで指定されたカラムをresultDataTableに登録
  • Y軸の値と対応する行を格納するための空の辞書(dict)を作成
  • 元のDataTableから1行づつ読み込んで dr 変数に格納
  • dr からX軸カラムの値を取り出し、resultDataTableのカラムとして存在しなければ
    その値をカラム名として追加
  • dr からY軸カラムの値を取得し、dict に登録されているか確認。
    登録されていればdict をキー(Y軸カラムの値)にしてバリュー(row)を取得
    無ければ新しいDataRowを作成し、row 変数に格納
  • ヘッダで指定されたカラムの値をdr から rowにコピーする
  • drから取得したY軸カラムの値をキー、上記で作成したrowをバリューとしてdictに登録
  • row を resultDataTableに登録
  • row[Y軸カラム」 に 値カラムの内容を代入
  • 上記④以降を繰り返す

ループの中でY軸とX軸で特定されるセルに値を書き込むということは、Y軸とX軸の組み合わせが複数ある場合、同じ場所に何度も異なる値が上書きされることになります。
本来は合計するとか平均値を取るなどの処置が必要ですが、どのような処置が必要かはケースバイケースになるため、今回紹介したソースコードは単純に上書きするだけにしています。
後ほど紹介する1か所に変更を加えるだけなので、皆さんの利用方法に合わせて修正して下さい。

ソースコード

以下にPivotメソッドのソースコードを紹介しておきます。
Y軸とX軸の組み合わせが複数存在する場合、メソッドの最後にある return 分の少し上に 下記の記述があります。

// ピボットテーブル内のyとxの交差点に値を設定します
row[x] = val;

ここでY軸とX軸で特定されたセルに値を書き込んでいますので、何らかの集計がしたい場合は、ここを修正して下さい。

テストプログラムのソースコード

動作確認用のテストプログラムのソースコードを掲載しておきます。 WPF で作成しており、.NET Core 6.0を使用しました。

以下がXAMLのコードです。

以下がC#のコードです。Pivotのソースコードは含まれていませんので、動作させたい場合は任意の位置にPivotのソースコードを追加して下さい。

まとめ

今回は DataTable をPivot(縦横変換)するためのC#のメソッドのソースコードと、テストプログラムを紹介しました。

ロジックはシンプルです。

  • 元のDataTableからDataRowを取り出すループの中で、空のDataTableに対して不足しているカラムと行を追加していく。
  • 既にカラムと行が存在すれば、そこに値を上書きする。

元のDataTableの各カラムのデータ型によっては、うまくいかないケースがあるかもしれませんが、データ型を合わせてあげれば動作するはずです。

皆さんのニーズに合わせてカスタマイズして使っていただければ幸いです。

よかったらシェアしてね!
  • URLをコピーしました!
  • URLをコピーしました!

コメント

コメントする

目次