CSVデータを取り出すには

◆PROCESSING 逆引きリファレンス

 カテゴリー:ファイル操作

CSVデータを取り出すには

【解説】

事務系のプログラムやビジネスプログラムを作成していると、時々CSVファイルを使いたい場面に出会います。

PROCESSINGにはCSVやTSVを簡単に扱える命令と、それを扱うのに適したTableという独自のクラスが用意されています。

CSVやTSVファイルを読み込む方法については「CSVファイルを読み込むには」記事で紹介しました。

ここでは読み込んだ結果得られる Tableクラスのインスタンス変数を用いて、データを取り出す方法を幾つか紹介したいと思います。

Tableクラスには、ここで紹介した命令以外にも便利なものがありますので、詳しくは公式リファレンスを参照してください。

 

【構文】

以下の命令はすべて Tableクラスのメソッドです。tbl がTableクラスのインスタンス変数という前提でお読みください。

読み込んだ行数を取得する

int   rowCount  =  tbl. getRowCount( ) ;

rowCount  : CSVまたはTSVファイルの行数

 

読み込んだ列数を取得する

int   colCount  =  tbl. getColumnCount( ) ;

colCount  : CSVまたはTSVファイルの列数

 

指定した行と列で値を取り出す

String  getStr      =  tbl. getString( int  row,   int  column  ) ;
String  getStr      =  tbl. getString( int  row,   String  colName  ) ;

int         getInt      =  tbl. getInt( int  row,   int  column  ) ;
int         getInt      =  tbl. getInt( int  row,   String  colName ) ;

float     getFloat  =  tbl. getFloat( int  row,   int  column  ) ;
float     getFloat  =  tbl. getFloat( int  row,   String  colName ) ;

row            : 0から始まる行位置
column    : 0から始まる列位置
colName : 列名(ヘッダありモードで読み込んでいる場合だけ利用可能)

 

特定の文字を含む行を探す

TableRow  tblRow  =  tbl. matchRow( String  regexp,   int  column ) ;
TableRow  tblRow  =  tbl. matchRow( String  regexp,   String  colName ) ;
Iterable<TableRow>  it  =  tbl. matchRows(  String  regexp,  int  column ) ;
Iterable<TableRow>  it  =  tbl. matchRows(  String  regexp, String  colName ) ;

regexp     : 探したい文字列
column    : 0から始まる列位置
colName : 列名(ヘッダありモードで読み込んでいる場合だけ利用可能)
tblRow    : 指定した文字列を含む行インスタンス(TableRow)
it   : 指定した文字列を含む行インスタンス(TableRow)のイテレータ集合

 

【注意】

読み込んだ行数を取得する

getRowCount( ) で、loadTable()命令で読み込んだファイルの行数を知る事が可能です。

ただしloadTable() する際にヘッダー有りを指定した場合は、ヘッダーを除く行数が戻される事に注意してください。

例えば上記のようなCSVファイルがあるとして、これを

  • loadTable( “hoge.csv”,  “header” ); で読み込んでいるなら1が
  • loadTable( “hoge.csv” ); で読み込んでいるなら2が

戻されます。

改行だけのファイルからでも行数を得ることができます。例えば以下のように改行が1つだけあるファイルを

  • loadTable( “hoge.csv”,  “header” ); で読み込んでいるなら0が
  • loadTable( “hoge.csv” ); で読み込んでいるなら1が

戻されます。

 

読み込んだ列数を取得する

getColumnCount( ) で、loadTable()命令で読み込んだファイルの列数を知る事が可能です。

上記のようなファイルなら、Number、Name、Kind、Weight の4列があるので、4が戻されます。

getRowCount( ) と同じく、改行だけしかないファイルからでも列数を得ることができます。例えば以下のように改行が1つだけあるファイルを読み込んでいる場合は、1が戻されます。

 

指定した行と列で値を取り出す

項目を文字列として取り出すなら getString()、整数として取り出すなら getInt()、小数値として取り出すなら getFloat()を使います。

いずれの命令も行位置、列位置は0から始まる整数です。

ヘッダの有り無しで行位置が変わることに注意してください。

またデータを半角シングルクォーテーション(‘)で囲んでいる場合や、データの前後にTAB文字や空白文字を含んでいる場合は、それらも含めて取り出される事にも注意してください。

取り出したデータのシングルクォーテーションや、空白、TAB文字が不要な場合は、自分たちのプログラムで除去する工夫が必要となります。

またgetInt() や getFloat() は数値に変換できる項目を取り出す用途で利用します。数値化できない文字列(例えば上記CSVの「コリー」など)を取り出すと、getInt() では0が、getFloat() では NaN (Not a Number)が戻されます。

列位置は数値以外にも、文字列(列名)で指定する事が可能です。例えば上記の例なら、「コリー」を取り出す際に tbl. getString( 1  ,  ”Kind”  ) ;  と指定することができます。

ただし列位置を文字列で指定するには、ヘッダ有りで読み込ませている必要があります。ヘッダ無しで読み込んだファイルを列名指定で取り出そうとすると、「This  table  has  no  header.  so  no  column  titles  are  set」 例外が発生します。

列名の大文字小文字、TABなどの制御文字や空白文字は、すべて正確に指定する必要があります。指定した列名が見つからないと、「The  table  has  no  column  named  XXXX(XXXXは指定した列名)」例外が発生します。

上記例なら、tbl. getString( 1  ,  ”KIND”  ); や tbl. getString( 1  ,  ” Kind”  ) ; はNGという事になります。

また同じ列名が複数ある場合は、最後に見つけた(最後尾にある)列側の値が戻されます。上記のようなファイルに tbl. getString( 0 ,  ”種類”  ); とすると、「秋田犬」が戻されます。

 

特定の文字を含む行を探す

読み込ませたファイルから、指定した列に特定の文字列を含むものがあるか検査して、その行全体を取り出す事が可能です。

tbl.matchRow() なら指定した文字を含む最初の行が、tbl.matchRows() なら全ての行が戻されます。

matchRow()、matchRows() 共に、戻されるのはTableRowクラスのインスタンスで、該当インスタンスには見つけた「行全体」の情報が含まれています。

例えば上記のようなCSVファイルに対し tbl.matchRow(  “秋田*”,  2  ) ;  と指定すると、2列目(種類の列)に「秋田」で始まるデータがあるか探して、最初に見つけた行(0行目の情報)が戻されす。

tbl.matchRows( “秋田*”,  2  ) ; なら、0行目と3行目の情報がイテレータとして戻されます。イテレータからは、Forループを用いることでTableRowの各情報を順次取り出すことが可能です。

探したい文字列には正規表現が使えるようですが、指定されたデータが見つからないと「NUll  Pointer  Exception」例外が発生するため、この命令を使う場合は適切な例外処理が必須となります。

 

【関連記事】


サンプルプログラム

以下のサンプルでは、下記のようなCSVファイル(TestCsv.csv)がdataフォルダ配下に格納されており、ヘッダー有りで読み込んでいる事が前提です。文字コードはUTF-8が前提です。


各項目間にある空白やTAB文字に注意してください。

  • 1行目の「ジョン」はシングルクォーテーション付きです。
  • 2行目の「ショコラ」はTAB文字付きです。
  • 3行目の「武蔵」は前後に全角SPACEを含んでいます。

CSVの行数と列数を取得する例:

上記ファイルの行数と列数を表示します。

<出力サンプル>
ファイルが読み込めた場合

ファイルが読み込めない場合

 

指定した行と列位置で値を取り出す例:

上記ファイルから1列目のデータ(Name列)を列番号で取得しています。各値の取り出され方に注意してください。

「ジョン」にはシングルクォーテーションが付いています。「ショコラ」の前にはTAB文字が付いています。「武蔵」の前後には全角SPACEが付いています。

<出力サンプル>

 

指定した行と列名で値を取り出す例:

先程とほとんど同じですが、1列目のデータ(Name列)を列名で取得しています。

<出力サンプル>

 

指定した行と列を数値として取り出す例:

犬の番号(0列目)と体重(3列目)を数値として取り出しています。

getFloat() で数値化できない項目を取り出すと NaN が戻されるので、(この例のCSVでは問題ないのですが)万が一の事を考えて対策を施してあります。

NaNがどうか調べるのに、if( weight == Float.NaN ){ などと比較して聞いてはいけません。例にあるように Float.isNaN() か、Double.isNaN() で調べてください。

<出力サンプル>

 

指定した文字を含む最初の行を取り出す例:

2列目(Kindの列)が “秋” で始まる行を探し、最初に見つけた行から犬の名前(1列目)を取り出して表示しています。

<出力サンプル>

 

指定した文字を含む全部の行を取り出す例:

先ほどと同様に2列目(Kindの列)が “秋” で始まる行を探していますが、今度は matchRows() を利用しています。

matchRows()は TableRowのイテレータを戻すので、Forループで順次取得します。

ついでに、取り出されたデータの前後から全角SPACE、シングルクォーテーション、TAB文字を取り除いて表示させています。

<出力サンプル>

 


PROCESSING逆引きリファレンス一覧 へ戻る

本ページで利用しているアイコン画像は、下記サイト様より拝借しております。各画像の著作権は、それぞれのサイト様および作者にあります。