【超入門】Loopを回せ! 〜KNIMEを使って複数のファイルを一気に読んでみよう〜
勝手に偉そうな命名をした"超入門シリーズ"ですが、これまでに
について紹介してきました。
さていよいよ今回はループの回し方について紹介したいと思います。
この3つが揃えば、データサイエンティストやプログラミングガチ勢ではない、私のような専門外の人間でも、ある程度のルーチンワークをKNIMEにお願いすることができるようになります。
今回は例として、
【複数のファイルを一気に全部読み込む】という作業にtryしてみます。
読み込むファイルの形式はsdfというものにして説明しますが、エクセルでもcsvでも、大体流れは同じです。
さて、状況のイメージです。
ひとつのフォルダに読みたいファイルが全て入っているものとします。今回の場合は、testという名前のフォルダにfile_0.sdf ~ file_9.sdfという10個のファイルが格納されています*1。これを一気に読んでいこうと思います。
あんまりピンとこないでしょうか?
- 10人から集めたファイルを一つにしたい
- 毎月のレポートを10ヶ月分まとめて解析したい
などなど、色んな場面が考えられると思うので、皆様の状況によく合うものをイメージすると活用に繋がるのではないでしょうか?
それでは、KNIMEの操作について紹介します。
まずは全体像のキャプチャを載せます↓
概要を書きます。
【List Files】でファイルの場所を取ってきて、それを【Table Row To Variable Loop Start】を使って、変数にすると共に、1つずつ【SDF Reader】に渡します。まず変数の1つ目の値由来のファイルが読み込まれ、その内容が【Loop End】までくると1サイクルが終了して、Loop Startから2つめのファイル名がSDF Readerに渡されます。全てのサイクルが終了するまで処理を繰り返します。
ノードひとつずつについて説明していきます。
List Files
指定した場所にはどんなファイルがあるのか教えてね!というノードです。
今回は私のdesktopにあるtestというフォルダを指定しています(冒頭のキャプチャです)。include sub foldersにチェックを入れると、指定したフォルダ内にさらにフォルダがある場合は、その中味についても教えてくれます。このノードではfilterをかけることも可能です。今回はnoneになっていますが、ファイル名や拡張子など所望の条件を指定することが可能です。実行結果を見てみます。
LocationとURLという2つのカラムを持つtableが吐かれます。
URL to File Path
今回のおまけ要素1です。URLの文字列(Locationでもいいんですが)をいい感じに細切れにしてくれます。
設定は簡単です。文字列としてURL(Locationでもいいです)を指定してapply-OKするだけです。実行結果はこうなります↓
親フォルダ、ファイル名、拡張子、ファイルのパスの4つに分けてくれます。続いて、このtableの内容を変数にします。
Table to Variable Loop Start
入力テーブルのデータを変数にしてループを開始します。入力テーブルが1行だった場合に使えるTable Row to VariableのLoop機能付きバージョンです。特に設定は不要です。Loop Endまで繋がずに、Table to Variable Loop Startを実行してみます。
maxiterations(全部でn周まわすよ!という意味)の値は10、current Iteration(いま何周目?の意味。なお1周目は0です)の値は0になっているのが確認できます。
またこの1周目のループでは、変数【File name】がfile_0という値であることがわかります。その他の変数もそれに対応するものになっていることが確認できます。
SDF Reader
SDF Readerの設定は、変数を使う場合にちょっとクセがありますので紹介します。
まずは、File selectionタブ内にて適当な名前でいいので、ファイル名のところに何か記述して下さい。今回の例では、ファイルの指定は変数を使って行いたいのですが、variableボタンはありません。ですので、Flow Variablesタブに移って設定を進めます。
urlsの0のところで、プルダウンからURL(もしくはLocation)を選びます。
この0のところが読み込みファイルの指定場所です。ゼロじゃわかんねーよ!と私がKNIMEを使い始めたときには若干にイライラしたものです。しかも、先ほど強調した
【File selectionタブで、なんでもいいからファイル指定するところに記述する】
をしていないと、このゼロが出てこないんです。
これが紹介したかったクセです。
ちなみに、Property handlingの設定はExtract all propertiesにしています。
構造情報とCHEMBLIDが情報として入っていますね。file_0には434のデータが入っていることも確認できます。ただこれだと本当にfile_0由来なのか、ちょっと分かりにくいので、この部分に関して調整していきます。
String manipulation
おまけ要素2です。このノードは過去記事で紹介してます。
今回は、データに【この情報は、どのファイル由来なの?】というのが後からわかるように、sourceというカラムを新規に作成し、元のファイル名をデータとして持たせようと思います。
string( )は括弧内の文字列をデータとして入力するときの書き方です。赤枠内に注目して下さい。流れてくる変数も使うことができます。マウスオンすると変数の現在値を確認することも可能です。ダブルクリックすればExpressionに反映されます。
string()としておいて、括弧の中にカーソルを置いて【変数:File name】をダブルクリックをすればキャプチャにあるように
string($${SFile name}$$)
となります。もちろん手入力でも構いません。
カラム名を"source"として実行すると次のようになります。
こうしておくと、どのファイル由来なのか、あとでわかりやすいですと思います。
Loop End
これは特に設定は不要です。繰り返しの作業をして溜まったデータをまとめて吐き出します。
全部で4335のデータがあることがわかりますし(ファイル10個分ってことね)、スクロールして確認すると由来となるファイル名もちゃんと入っています。
注意すべき点としては
【Loop Endに入るデータは全ての周で、カラム(名前・属性)が全く同じ】
でなくてはなりません。違うカラムがあると、「なにこれ、さっき周とデータの形式が違うんだけど?まとめられないんだけど?」と怒られてしまいます。
なので場合によってはLoop endの前にcolumn filterを挟んで内容を調整したりするなど工夫が必要な場合もあります。
全体としての注意点としては、loop startとendがちゃんと1対1になっていることです。どの区間が繰り返しのエリアなのかがはっきりわかるように書かないと、KNIMEも「それじゃわからないよー」と言って止まってしまいます。
ちょっと長くなりましたが、いかがでしたか?
ループを回すと、計算時間はちょっと伸びるので回避できる書き方があるならば、それを模索するのもよいですが、まずはループを回せることが重要かなと思います。
(for文なのか、リスト内包表記なのかという感じですか?私はpythonはかじり始めなのであまりよくわかりませんけど)
変数・ループをうまく活用しながら、多彩なノードを間に組み込んで
まずはルーチンワークの半自動化
に是非挑戦してみてください。*2