SHOEISHA iD

※旧SEメンバーシップ会員の方は、同じ登録情報(メールアドレス&パスワード)でログインいただけます

CodeZine編集部では、現場で活躍するデベロッパーをスターにするためのカンファレンス「Developers Summit」や、エンジニアの生きざまをブーストするためのイベント「Developers Boost」など、さまざまなカンファレンスを企画・運営しています。

PerlによるCSVファイルの高速集計

PerlによるCSVファイルの高速集計

CSVを自在に扱って、業務を効率化しよう

  • X ポスト
  • このエントリーをはてなブックマークに追加

エンジニアにとって、データの編集や集計の作業は、プログラムの開発と同じくらい頻繁に発生する作業です。その中でもCSVファイルを触らねばならない機会は、いまだに多いのではないでしょうか? ここでは、その厄介なCSVファイルと上手に付き合うノウハウを紹介します。

  • X ポスト
  • このエントリーをはてなブックマークに追加

はじめに

 Perlと言えば、いまだにCGIを思い浮かべる人は多いと思います。しかし、Perlは決してそれだけの言語ではなく、その言語仕様はテキストファイルを処理し、集計結果をレポートするのに非常に向いています。特によく利用されるテキストファイルとして、CSV形式が挙げられます。CSVを集計したい場合、Excelに読み込ませて集計関数やマクロを駆使しているという人も多いかと思いますが、Perlを利用することで、高度な集計作業を簡単かつ高速にできます。

 本稿では、筆者がPerlでCSV集計を行う際によく使うノウハウを紹介したいと思います。

対象読者

  • まだ、Perl=CGIと思っている方。
  • 65,536件を超える大量のCSVデータを前に、手も足も出なくなっている方。

必要な環境

  • テキストエディタ。
  • Perl 5.8.X。ただし、ほとんどのコードはそれ以下のバージョンでも動きます。

Perlのインストール

 Windowsユーザーの方は、ActiveStateのサイトからActivePerlの最新版をダウンロードし、インストールしてください。ここではCドライブに「usr」というフォルダを作り、そこにインストールしてください。Mac OS X、UNIX/Linux系の方は、ほとんどの場合デフォルトでインストールされています。

サンプルデータ

 実際の動作を確認できるように、サンプルデータを用意しました。Windows環境で試すときは「サンプルデータ(Windows用:Shift-JIS、CRLF)」、Unix環境で試すときは「サンプルデータ(Unix用:UTF-8、LF)」を、それぞれダウンロードしてください。

条件にマッチする行数を数える

 まずは基本形として、CSVファイルの読み込み処理をPerlで記述してみます。ですが、ただの読み込みでは実用的でないので、「条件にあてはまる行が何行存在するのか」を数えるようにしてみます。

 次のような「customer_data.csv」ファイルがあるものとします。

customer_data.csv
02547,佐藤大輔,25,北海道,苫小牧市
15983,田中久志,19,沖縄県,那覇市
00893,本間雅洋,29,神奈川県,横浜市
 :
 :(以下、100,000件)
 :

 「customer_data.csv」は、「顧客ID」「氏名」「年齢」「都道府県」「市区」の5つのカラムを含むカンマ区切りのファイルであり、100,000件のデータを含んでいます。ここで、100,000件という前提条件が重要になります。なぜなら、コンピュータでデータ処理をする場合、メモリの使用量はパフォーマンスに重大な影響を与えるからです。このフォーマットの文書が、UTF-8で100,000件書かれていた場合、想定されるファイル容量は約4MBです。最近のPCのメモリ事情を考えれば、この程度の量であればすべてをメモリにのせてもまったく問題がありません。筆者の感覚ですと、データが100万件以内であれば、すべてメモリにのせて処理できると思っています。よって、以降はメモリのことについて深く考えずにスクリプトを書くこととします。

 では、これらのデータの中に、年齢が20代の人が何人含まれるているのかを、Perlを使って数えてみます。Perlは、テキストエディタでプログラムを記述し、DOSプロンプトやシェル内からコマンドで起動することができます。また、Windowsの場合は、perlスクリプトと「perl.exe」が拡張子.plで紐づけられるため、ダブルクリックで実行することもできます。ただし、ダブルクリックによる実行は、実行結果のウィンドウがすぐに閉じてしまうため、スクリプトにエラーがあった場合に追跡が困難になります。慣れるまでは、DOSプロンプトから実行する方が良いでしょう。

 では、早速テキストエディタを立ち上げ、次のようにスクリプトを書きます。スクリプトは「customer_data.csv」と同じディレクトリに「count.pl」という名称で保存してください。

count.plの骨組み
open(IN, 'customer_data.csv');
while(<IN>){
    chomp;
    my @d = split(/,/, $_);
    # ------------------------
    # ここに、集計処理を書く
    # ------------------------
}
close(IN);

 これが、PerlでCSVを扱う場合の基本形となります。最初にopen()で、ファイルを開きます。次のwhile(<IN>) { ... }は、開いたファイルを1行ずつ繰り返し処理することを意味します。Perlでは引き数を省略した場合は$_が暗黙的に使われることになっているので、おのおのの行の内容は$_に保持されています。chompは、末尾の改行コードを取り除く関数です。ここでも引き数を省略し、$_に対して処理させています。splitは文字列を分解する関数です。引き数にカンマを渡し、カンマで文字列を分解して@dという配列に代入しています。Perlの文法では、配列変数には先頭に@、その個々の要素にアクセスする場合には先頭に$をつけて、大括弧[]で添字を指定します。

 例えば1行目の処理であれば、@dには次のような内容が入っています。

行をsplitした結果
$d[0] => 02547
$d[1] => 佐藤大輔
$d[2] => 25
$d[3] => 北海道
$d[4] => 苫小牧市

 後は、集計処理を書けば完成します。20代であればカウンタを1追加する処理を記述し、最後にカウンタの内容をプリントさせます。スクリプトは次のようになりました。ステップ数で言えば10行以下です。

count.plの完成
my $count = 0;

open(IN, 'customer_data.csv');
while(<IN>){
    chomp;
    my @d = split(/,/, $_);

    # 20~29歳ならカウントアップ
    if(20 <= $d[2] && $d[2] <= 29){
          $count++;
    }
}
close(IN);

# 結果を表示
print $count, "\n";

 では、これを実行します。DOSプロンプト(又はシェル)を開き、まずは「customer_data.csv」と「count.pl」の置いてあるディレクトリに移動します。GUIのある環境であれば、スクリプトのアイコンをプロンプトにドラッグすると、パスを手で打つ手間がなく楽です。ファイル名を消して、cdしてください。

DOSプロンプト
> cd D:\csvdata\

 後はスクリプトを実行するだけです。perlコマンドの後にスクリプト名を指定します。CSVファイルの名前はスクリプト内に書かれているので必要がありません。

DOSプロンプト
> perl count.pl
36457

 スクリプトは一瞬~数秒で終わるはずです。20代の人は36,457人いるようです。

次のページ
連想配列を利用する

この記事は参考になりましたか?

  • X ポスト
  • このエントリーをはてなブックマークに追加
PerlによるCSVファイルの高速集計連載記事一覧
この記事の著者

hiratara(ヒラタラ)

1977年に苫小牧市で生まれる。北海道大学理学部数学科卒。小学生の頃、両親に買い与えられたMZ-2500でプログラミングを始めた。学生時代、CGIの自作に没頭し、それ以降WEB開発の魅力に憑かれる。社会人になっても数学好きは変わらず、専門書を買い集めるのが最近の趣味。id:hirataraにてblogを執筆...

※プロフィールは、執筆時点、または直近の記事の寄稿時点での内容です

この記事は参考になりましたか?

この記事をシェア

  • X ポスト
  • このエントリーをはてなブックマークに追加
CodeZine(コードジン)
https://codezine.jp/article/detail/904 2007/03/19 20:07

おすすめ

アクセスランキング

アクセスランキング

イベント

CodeZine編集部では、現場で活躍するデベロッパーをスターにするためのカンファレンス「Developers Summit」や、エンジニアの生きざまをブーストするためのイベント「Developers Boost」など、さまざまなカンファレンスを企画・運営しています。

新規会員登録無料のご案内

  • ・全ての過去記事が閲覧できます
  • ・会員限定メルマガを受信できます

メールバックナンバー

アクセスランキング

アクセスランキング