LoginSignup
0
1

More than 1 year has passed since last update.

ひどい横持ちデータを八方駆使してなんとか縦持ちデータにする

Last updated at Posted at 2023-02-11

ここにひどいデータがある。

こんな感じのUIで表示されているが

ユニークコード :1
編集履歴メモ:

編集日 メモ
2023/01/01 いろは
2023/01/15 にほへ
2023/02/01 とちる

データベース上ではこんな感じで保存されている。

unique_cd date_col text_col
1 2023/01/01,2023/01/15,2023/02/01 いろは,にほへ,とちる
2 1998/10/01,2010/1/1
3 2020/01/20 ABC
4 2020/01/20,2020/02/20 ,ふがふが

こんなデータが数万ユニークコード分ある。これをExcelでなんとかしていきたいと思う。

前提

  • カンマ区切りのデータになっており、メモ内の記号はエスケープされていないが、デリミタ文字は利用されていない。
  • 日付とメモの個数は『基本』合致しているが、移行の影響で日付のみ登録されているデータがある。
  • 正常に登録されているデータはメモが空白でもデリミタで区切られている。
  • データベース上のデータは任意のデリミタファイルへ出力できる。

やっていきます。

まずユニーク対1データのペアにする。

unique_cd date_col
1 2023/01/01,2023/01/15,2023/02/01
2 1998/10/01,2010/1/1
3 2020/01/20
4 2020/01/20,2020/02/20

これをちゃんとセルが分かれた横持ちデータにする。

  1. date_colを列選択した状態で『データ>区切り位置』を選択する
    image.png
    2.コンマ区切りでの分割を選択してひどいデータをとりあえずセル区切りにする。
    image.png
    image.png
  2. Ctrl+Endを押し、最終列にジャンプする。
    image.png
  3. 1行目へ移動し、=COLUMN()を入力し列番号をつける。
    image.png
  4. ユニークコード以外の列名を番号にする。
    image.png

ピボットテーブルウィザードでテーブルに変換する。

呪文の時間です。

  1. Alt->D->Pと入力し、ピボットテーブルウィザードを表示し、複数のワークシート範囲を選択する。次へ
    image.png
    2.指定を選択し、先程のデータ範囲を指定する。
    ※データ件数が多いとかなり待つ・・・
    image.png
    3.新規ワークシートに作成するとピボットテーブルができます。右下をダブルクリック
    image.png
    image.png
  2. 値と列の組み合わせのデータができました。あとはこれを合体させれば完了です。よかったですね。
    image.png

よくなかった

例のデータは量がザコザコでしたが、実際にやりたかったデータは3万行×4千列。縦持ちにすると1億2千万行となり、このざまです。
image.png

続行するとピボットまではなんとかできますが、テーブルに展開することは当然できません。Excelの限界を超えています。

次の手-PowerShellでなんとかする

TSVファイルでデータを取り出す。

image.png
中身はこんな感じ

UNIQUE date
1 2023/01/01,2023/01/15,2023/02/01
2 1998/10/01,2010/1/1
UNIQUE memo
1 いろは,にほへ,とちる
2

これをこうしてこうじゃ

泥くさいPowershellを書きます。前提として商品コード順にそれぞれソートされているので、値の合致が取れている事を前提にデータを分割し、再構成、バッファをもたせながら書き込みを行います。

$date = (Import-Csv -Path .\dates.tsv -Delimiter "`t")
$memos = (Import-Csv -Path .\memos.tsv -Delimiter "`t")
#出力ファイルパス
$exportfile = ".\tatemochi.csv"
#出力ファイルにヘッダを書き込む&初期化
Set-Content $exportfile "UNIQUE,date,memo"
$total = $date.Count
$tmpData = ""
# 追記する頻度
$writePer = 1000
$writeCnt = -1
for ($i = 0; $i -lt $date.Count;$i++){
    Write-Progress -Activity "進捗" -Status $i"/"$total  -PercentComplete ($i/$total)
    # 値をSplitし、件数を比較する。
    $datearray = $date[$i].date.Split(",")
    $memoarray = $memos[$i].memo.Split(",")
    if($datearray.count -eq $memoarray.Count){ #値が合致したら縦持ちにする。
        for($c=0;$c -lt $datearray.Count;$c++){
            $tmpData += (@($date[$i].UNIQUE , $datearray[$c] , $memoarray[$c]) -join ",")+"`r`n"
        }
    }
    if($writeCnt -eq $writePer ){
        Add-Content $exportfile $tmpData -NoNewline
        $tmpData = ""
        $writeCnt = 0
    }
}
0
1
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
1