知ろう!使おう!HDF5ファイル!/pycon-jp-2019-talk

D484f3a4d5f516f943b29b9ff55a2040?s=47 thinkAmi
September 17, 2019

 知ろう!使おう!HDF5ファイル!/pycon-jp-2019-talk

PyCon JP 2019の発表資料です

D484f3a4d5f516f943b29b9ff55a2040?s=128

thinkAmi

September 17, 2019
Tweet

Transcript

  1. 2.

    お前誰よ / Who are you ? @thinkAmi Python/Django/Web アプリケーションエンジニア Blog

    :メモ的な思考的な (http://thinkami.hatenablog.com/) ( 株) 日本システム技研 PyCon JP 2019 Gold Sponsor (2016-18 Silver Sponsor) ギークラボ長野 Python Boot Camp in 長野 みんなのPython 勉強会 in 長野
  2. 12.

    HDF 5 HDF Hierarchical Data Format 階層構造を持ったデータフォーマット The HDF Group

    がサポート https://www.hdfgroup.org/ HDF5 ファイルの開発を進めるNPO 団体 米国立スーパーコンピュータ応用研究所 (NCSA: National Center for Supercomputing Applications) 発
  3. 21.

    HDF5 ファイルと言語バインディング 公式 C, Fortran, C++, Java, P/Invoke サードパーティ Python,

    R, Julia, 他 参考:HDF5 Language Bindings https://portal.hdfgroup.org/display/HDF5/HDF5+Language+Bind ings
  4. 27.

    HDFView とは The HDF Group が提供しているビューワー & エディタ Open JDK

    11 で動作 HDF5 の他、HDF4 もサポート 公式ページ https://portal.hdfgroup.org/display/HDFVIEW/HDFView
  5. 31.

    ライブラリの比較 名前 Layer 特徴 h5py 低 HDF5 API を忠実に再現 PyTables

    高 HDF5 ファイルを拡張、テーブル概念の追加やパフ ォーマンス改善等を実装。よりデータベースに近い 詳細については、各ライブラリのFAQ を参照 http://docs.h5py.org/en/stable/faq.html#what-s-the-difference- between-h5py-and-pytables http://www.pytables.org/FAQ.html#how-does-pytables-compare- with-the-h5py-project
  6. 32.

    h5py とPyTables のデータ互換性 例:PyTables で作った文字列データを、h5py で読む # PyTables でファイルを作る with

    tables.open_file(filepath, 'w') as f: dataset = f.create_vlarray('/', 'str_data', atom=VLUnicodeAtom()) dataset.append(' シナノゴールド') # PyTables で開く with tables.open_file(filepath, 'r') as f: node = f.get_node(where='/', name='str_data') for row in node.iterrows(): print(row) # => シナノゴールド # h5py で開く with h5py.File(filepath, mode='r') as f: dataset = f['str_data'] print(dataset[0]) # => [12471 12490 12494 12468 12540 12523 12489]
  7. 35.
  8. 36.

    HDF5 ファイルを開く 書込・読込は、 mode で切り替え import h5py output = OUTPUT_DIR.joinpath('use_h5py.h5')

    # with を抜けると、書き込まれる with h5py.File(output, mode='w') as file: # 処理
  9. 38.

    Dataset ( 文字列) 作成 ds_str = group.create_dataset( # h5py 2.9

    までは、 dtype=h5py.special_dtype(vlen=str) name='name', shape=(1,), dtype=h5py.string_dtype()) ds_str[0] = ' シナノゴールド'
  10. 39.

    Dataset ( 画像) 作成 # 画像を読み込み image_path = INPUT_DIR.joinpath('shinanogold.png') with

    image_path.open(mode='rb') as img: image_binary = img.read() # NumPy 配列化 image_data = np.frombuffer(image_binary, dtype='uint8') # バイナリの型定義 TYPE_OF_BINARY = h5py.special_dtype(vlen=np.dtype('uint8')) # 画像を設定 ds_img = group.create_dataset( 'image', image_data.shape, dtype=TYPE_OF_BINARY) ds_img[0] = image_data
  11. 40.

    Dataset (Excel) 作成 画像と変わらない excel_path = INPUT_DIR.joinpath('mybook.xlsx') with excel_path.open(mode='rb') as

    excel: excel_binary = excel.read() # np.frombuffer() を使うところだけが違う excel_data = np.frombuffer(excel_binary, dtype='uint8') ds_excel = group.create_dataset( 'spec', excel_data.shape, dtype=TYPE_OF_BINARY) ds_excel[0] = excel_data
  12. 41.

    Attribute 作成 Group, Dataset のどちらにも作成可能 # Group のAttribute group.attrs['title'] =

    ' りんご情報' # Dataset のAttribute ds_str.attrs['color'] = ' 黄色系'
  13. 42.
  14. 44.

    Dataset ( 画像) の読込 画像も、Dataset の取得方法は同じ # HDF5 ファイルから、image の入ったDataset

    を取得 rds_img = file['apple/image'] # Pillow で開く Image.open(io.BytesIO(rds_img[0])).show()
  15. 45.

    Dataset (Excel) の読込 # HDF5 ファイルから、Excel の入ったDataset を取得 dataset =

    f['apple/spec'] # 一度ファイルとして保存 with excel_path.open('wb') as w: w.write(dataset[0]) # 拡張子"xlsx" に関連付けされたアプリで開く os.system(f'open {excel_path}') # Mac の場合
  16. 46.
  17. 47.

    検索 (h5py) visititems() で各オブジェクト(Group/Dataset) にアクセス可能 コールバック関数内で絞り込むことも可能 def print_callback(name, obj): #

    コールバック関数 print(f'name: {name}, type: {type(obj)}') # データの検索 file.visititems(print_callback) # 結果 ( 見栄えを調整) # name: apple, type: <class 'h5py._hl.group.Group'> # name: apple/excel, type: <class 'h5py._hl.dataset.Dataset'> # name: apple/image, type: <class 'h5py._hl.dataset.Dataset'> # name: apple/name, type: <class 'h5py._hl.dataset.Dataset'>
  18. 49.
  19. 50.

    gzip 圧縮 10MB のバイナリをDataset に入れると、無圧縮では約170MB create_dataset() の引数 compression に圧縮形式 (gzip

    など) を入れる with h5py.File(compression_file_path, mode='w') as file: compression = file.create_dataset( 'big_size_data', big_size_data.shape, dtype=TYPE_OF_BINARY, # 圧縮形式を指定 compression='gzip') compression[0] = big_size_data # HDF5 ファイルのサイズを表示 print(f'{str(os.path.getsize(compression_file_path)).rjust(10)} [compress]') # => 10003716 [compress] ( 約10MB)
  20. 52.

    ところで import pathlib import h5py BASE_DIR = pathlib.Path(__file__).resolve().parents[0] OUTPUT_DIR =

    BASE_DIR.joinpath('output', 'h5py') output = OUTPUT_DIR.joinpath('use_h5py.h5') with h5py.File(output, mode='w') as file: ...
  21. 53.

    HTTP + HDF5 ファイル h5serv HDF REST API に準拠し、HTTP でHDF5

    ファイルを操作 Tornado ベース The HDF Group のリポジトリにて提供 https://github.com/HDFGroup/h5serv
  22. 56.

    h5serv でDataset 作成 Dataset の型定義をPOST URL_BASE = 'http://test.example.com:5000/' str_type =

    {'charSet': 'H5T_CSET_UTF8', 'class': 'H5T_STRING', 'strPad': 'H5T_STR_NULLTERM', 'length': 'H5T_VARIABLE'} payload = {'type': str_type, 'shape': 1} res1 = requests.post( URL_BASE + 'datasets', json=payload ).json()
  23. 57.

    h5serv でDataset 作成 Dataset の中身をPUT url = URL_BASE + 'datasets/'

    + res1.get('id') + '/value' res2 = requests.put( url, json={ 'value': ' ワールド' } )
  24. 58.

    h5serv で作成されたもの 2 つのHDF5 ファイル 全体の構造を管理するHDF5 ファイル (mytoc.h5) データが格納される実際のHDF5 ファイル

    (test.h5) $ python h5serv --port=5000 --toc_name=mytoc.h5 --domain=example.com URL_BASE = 'http://test.example.com:5000/'
  25. 62.

    h5pyd HDF REST API のクライアントライブラリ The HDF Group のリポジトリにて提供 https://github.com/HDFGroup/h5pyd-

    h5py とほぼ互換のAPI を持つ 少し書き換えるだけで、既存コードのHTTP 化が可能
  26. 63.

    h5serv とh5pyd を使う サーバーで、h5serv を起動 クライアントで、h5pyd を使ったスクリプトを実行 with h5pyd.File('test.example.com', mode='w',

    endpoint='http://localhost:5000') as file: ds_str = file.create_dataset(name='hello', data='world', dtype='S6') # byte 型になるので、デコードしておく print(file['hello'].value.decode('utf-8')) # => hello
  27. 65.

    HSDS HSDS = Highly Scalable Data Service The HDF5 Grouop

    のリポジトリにて提供 https://github.com/HDFGroup/hsds クラウドネイティブな構成 データの保管先はAWS S3
  28. 71.

    HDF5 のバージョン HDF5 x.y.z 現在は、2 系統 HDF5 1.8.x 系 HDF5

    1.10.x 系 ライブラリによっては、1.8.x しかサポートしてない場合も
  29. 72.

    ライフサイクル マイグレーションページに記載あり https://portal.hdfgroup.org/display/HDF5/Migrating+from+HDF5 +1.8+to+HDF5+1.10 1.8 系:2020 年5 月でパッチリリース終了 HDF HDF5

    における境界外読み取りに関する脆弱性 https://jvndb.jvn.jp/ja/contents/2019/JVNDB-2019- 002044.html 1.12 系:2019 年夏にリリース予定( だった)
  30. 74.

    h5py で使われるバージョン HDF5 のライブラリ libhdf5 を自動的で検知・利用 自分で指定することも可能 $ brew install

    hdf5 /usr/local/Cellar/hdf5/1.10.5_1 $ export HDF5_DIR=/usr/local/Cellar/hdf5/1.10.5_1 $ pip install --no-binary=h5py h5py >>> h5py.version.info h5py 2.10.0 HDF5 1.10.5 # 指定したバージョン
  31. 76.

    まとめ 科学技術分野以外でも、HDF5 ファイルは手軽に使える Python ライブラリが充実している h5py, PyTables, h5serv, h5pyd, HSDS

    ローカルだけでなく、サーバー・クラウドでも利用可能 今後もHDF5 ファイルには機能が追加されていく予定
  32. 77.

    次のステップ 書籍「Python and HDF5 」(Andrew Collette 著、米オライリー) Python ライブラリの扱い方 意外と奥が深い、HDF

    の世界(Python ・h5py 入門) - Qiita https://qiita.com/simonritchie/items/23db8b4cb5c590924d95 Getting started with HDF5 and PyTables - PyCon Slovakia(SK) 2018 https://pyvideo.org/pycon-sk-2018/getting-started-with-hdf5- and-pytables.html
  33. 78.

    公式情報 The HDF Group のtwitter https://twitter.com/hdf5 HDF Forum https://forum.hdfgroup.org/latest SlideShare

    The HDF-EOS Tools and Information Center https://www.slideshare.net/HDFEOS Youtube https://www.youtube.com/channel/UCRhtsIZquL3r-zH-R-r9-tQ
  34. 81.

    h5serv を使うための準備 自分の端末で使う場合、hosts ファイルに設定 < ファイル名>.< 適当なドメイン> h5serv が動作している example.com

    にアクセスすると、 test.h5 フ ァイルを操作できるよう設定 127.0.0.1 test.example.com domain オプションで、ドメインを指定して起動 $ python h5serv --port=5000 --toc_name=mytoc.h5 --domain=example.com
  35. 82.

    h5serv を使うための準備 操作対象のファイルを作成 中身は空で問題ない p = Path(__file__).resolve().parents[0].joinpath('h5serv', 'data', 'test.h5') with

    h5py.File(p, mode='w') as f: pass この時点での data ディレクトリ構成 $ tree . ├── public/ ├── readme.txt └── test.h5
  36. 83.

    h5serv での動作確認 型定義を作成 str_type = {'charSet': 'H5T_CSET_UTF8', 'class': 'H5T_STRING', 'strPad':

    'H5T_STR_NULLTERM', 'length': 'H5T_VARIABLE'} payload = {'type': str_type, 'shape': 1} res1 = requests.post( URL_BASE + 'datasets', json=payload ).json()
  37. 85.

    バージョン (HDF5 x.y.z) x: major version number ライブラリやファイルフォーマットの大きな変更あり y: minor

    version number 新しい機能によるファイルフォーマットの変更 偶数はstable 、奇数はdevelop z: release number バグ修正等ライブラリの改善、フォーマットの変更なし https://portal.hdfgroup.org/display/HDF5/HDF5+Library+Release+ Version+Numbers