Pythonでzipファイルを解凍せずに中身のテキストファイルを読み込む

10万件程度のテストデータが欲しい時、よく郵便番号のデータを使わせてもらっています。

郵便番号データダウンロード
http://www.post.japanpost.jp/zipcode/dl/kogaki.html


今までlzh形式で圧縮されたデータしか公開されていないと思っていたのですが、
よくみるとzip形式のデータも公開されています。

126_01.png


zip圧縮されたファイルは約1.8MB。
解凍すると12.2MB。

zip圧縮したファイルを直接読み込んで、直接郵便番号と住所の情報を
加工できないか考えてみました。





Pythonでzipファイル



以前、zipファイルの作成は試したことがあります。

Pythonでrarファイルを解凍し、zipで圧縮する
http://symfoware.blog68.fc2.com/blog-entry-908.html


同じノリで、zipファイルの情報を取り出してみます。


  1. # -*- coding:utf-8 -*-
  2. import zipfile
  3. with zipfile.ZipFile('ken_all.zip', 'r') as post:
  4.     
  5.     # zipファイルを開いて、中に格納されいるファイル名を表示
  6.     for info in post.infolist():
  7.         print(info.filename)





実行してみると、中に格納されているファイル「KEN_ALL.CSV」の
名前が表示されました。

126_02.png








KEN_ALL.CSVを読み込む




ファイルの内容を取り出すには、readすれば良さそうだったので、
うっかりこんなプログラムを書いて実行してしまいました。

※12万件の郵便番号データがコンソールに表示され、えらいことになります。


  1. # -*- coding:utf-8 -*-
  2. import zipfile
  3. with zipfile.ZipFile('ken_all.zip', 'r') as post:
  4.     
  5.     # zipファイルを開いて、中に格納されいるファイル名を表示
  6.     for info in post.infolist():
  7.         print(info.filename)
  8.         
  9.     # KEN_ALL.CSVの内容を取得
  10.     print( post.read('KEN_ALL.CSV') )
  11.     





これでは使いやすいように加工できないので、一行ずつ
データを取り出す方法を考えてみました。

StringIOを使ってやります。


  1. # -*- coding:utf-8 -*-
  2. import zipfile
  3. import cStringIO
  4. with zipfile.ZipFile('ken_all.zip', 'r') as post:
  5.     
  6.     # zipファイルを開いて、中に格納されいるファイル名を表示
  7.     for info in post.infolist():
  8.         print(info.filename)
  9.         
  10.     # KEN_ALL.CSVの内容を取得し、StringIOでくるむ
  11.     f = cStringIO.StringIO(post.read('KEN_ALL.CSV'))
  12.     
  13.     for line in f:
  14.         print( line )
  15.         
  16.         #デバッグ用に一行表示したらループを抜ける
  17.         break




126_03.png

文字化けしていますが、1行分のデータを取り出せています。
後もう一息、CSVファイルはms932で保存されているので、unicodeに変換。



  1. # -*- coding:utf-8 -*-
  2. import zipfile
  3. import cStringIO
  4. with zipfile.ZipFile('ken_all.zip', 'r') as post:
  5.     
  6.     # zipファイルを開いて、中に格納されいるファイル名を表示
  7.     for info in post.infolist():
  8.         print(info.filename)
  9.         
  10.     # KEN_ALL.CSVの内容を取得し、StringIOでくるむ
  11.     f = cStringIO.StringIO(post.read('KEN_ALL.CSV'))
  12.     
  13.     for line in f:
  14.         # ms932からunicodeオブジェクトに変換
  15.         print(unicode(line, 'ms932'))
  16.         
  17.         #デバッグ用に一行表示したらループを抜ける
  18.         break




126_04.png



これで、ダウンロードしたファイルを一旦解凍せずに、
郵便番号と住所のテストデータが加工できそうです。






【参考URL】

13.5. zipfile — ZIP アーカイブの処理
http://www.python.jp/doc/release/library/zipfile.html

7.5. StringIO — ファイルのように文字列を読み書きする
http://www.python.jp/doc/release/library/stringio.html




関連記事

コメント

プロフィール

Author:symfo
blog形式だと探しにくいので、まとめサイト作成中です。
https://symfo.web.fc2.com/

PR

検索フォーム

月別アーカイブ