Labviewで大容量CSVファイルから指定ラベル値のみを抽出(フリー)
・背景
今日のデータ処理の現場では、バイナリ形式データフォーマットを用いる事でメモリ削減、ビッグデータ処理に最適化されたアルゴリズムによる処理負荷の削減等により、解析工数削減が行われている。
しかし、特定の分野における解析力と、ビッグデータの取り扱い手法は全くの畑違いであり、両者の知見を持ち合わせた解析者は未だに少ないのが現実である。(私の感覚では、メモリ空間のデータフローを意識したプログラミングは2020年で終了したような気がします。コンパイラやハードの進化の恩恵でしょうか。)
そのため、Excelやフリーの表計算ソフトを用いて、数GBにも及ぶCSVファイルを何とかして操作しようとする人が後を絶たないのが現実である。
もちろん、表計算ソフトの便利さを否定するつもりではない。普及率や扱いやすさ、一番の要である関数の取り扱いやすさにおいて、それの右に出るモノは居ないと私自身も感じている。
こういった背景から、Labviewを用いてデータの一次処理(データ抽出)を目的としたVIをここに残す。
・概要
サンプルとして、図1の約450MBのcsvデータを用意した。
内容は、一行目はラベル値の名前、二行目以降は数値データである。
ここから、図2の抽出したいラベル名"Filterlist"を基に、csvデータのラベル名に部分一致で検索を掛ける。
部分一致したラベル名の列を抜き出し、新たなcsvデータとして出力する。
以上がVIの挙動である。
![](https://assets.st-note.com/img/1679758227037-OPcJa2P4t6.png?width=1200)
![](https://assets.st-note.com/img/1679758458739-skDIhJsMJ1.png)
・VI
とりあえずざっと書いてみる。
データの操作、変数の使用は必要最小限にするよう意識しました。
あとループ入口のトンネルも大容量配列ではNGです。できるだけシフトレジスタを使用します。
連結の追加もメモリ空間を連続して操作するので、あらかじめ2D配列を想定される大きさに初期化して、配列置換を使います。
※1:Whileループは実行時間を測定するために置いています。本当はいらないです。
※2:一段目のforループは、複数csvを一つにmergeするための処理を作ろうとして置いています。これもいらないです。
![](https://assets.st-note.com/img/1679771572973-dN2oEhwZeR.png?width=1200)
![](https://assets.st-note.com/img/1679758904525-IVzHCEh821.png)
・実行結果
用意したcsvファイルは、行数200,000、列数187です。
その内、filterlistに用意したラベル数は11。
抽出後のラベル数は22となっていました。(なぜかラベルの順番が逆になっている・・・)
以下にcsvファイル、filterlist、抽出後ファイルを置いておきます。
https://1drv.ms/u/s!AvwG8AAVskRti7Y4Ii-rJkUBWaoaig?e=MzgNmv
・実行速度の改善
とりあえず走らせてみました。
n1: 15.18sec
n2: 13.77sec
n3: 15.65sec
n4: 15.20sec
n5: 14.32sec
大体15秒といったとこでしょうか。
もう少し改善してみます。
・レジスタ格納やめて、直にドライブ保存してみる。
ボトルネックである大容量レジスタが無くなるので、大幅な改善が期待できるが・・・
→60秒以上掛かるのと、メモリ占有量も大して変わらず。
csv入力からのレジスタから、配列削除で削っていけば、csv出力分のレジスタが不要になるので、高速化・メモリ節約になるのでは?
→これも40秒以上掛かるため没。
スプレッドシートに書き込みブロックを分解し、サブvi入力部の変数使用をやめる。
→効果が無かった。データフローはコンパイラで最適化されているのかな?