福岡は今日も雨

情報系大学生のブログ。主に技術,音楽について。

ファイル入出力のあれこれ(バイナリ編)

昨日はcsvやら, エクセルデータの読み書きを見てきた. 今日はバイナリのデータでそれらを見る.
あとpandasも今日中に見ていく.

pickle

Pythonのオブジェクトをバイナリでそのまま保存/読み込みをする時に利用することができる.

import pickle

my_data = [1, 2, 3]

#ファイルに書き込み
with open('pickle1.pickle', 'wb') as f:
    pickle.dump(my_data, f)

#ファイルから読み込み
with open('pickle1.pickle', 'r') as f:
    pickle.load(f)

複数変数のpickle化は, 以下のように連続して書けばいい

import pickle
import numpy as np

a = np.float(2.3)
b = np.array([[1.1, 2.2, 3.3], [4.4, 5.5, 6.6]])
c = {'yokohama':1, 'tokyo':2, 'nagoya':3}

with open('pickle1.pickle', 'wb') as f:
	pickle.dump(a, f)
	pickle.dump(b, f)
	pickle.dump(c, f)

これだと次の問題が生まれる.
(1)順番にloadしなくては使えなくなる. いくつdumpされているのかがわからない場合もあり, try文で例外を見つける必要がある

(2)変数の名前が損なわれる. もう一回自分で付け直さなければならない

そこで, 辞書型でデータを活用するのが良いのだそう
それなら,(1)の問題も消え, execで実行していくことで,キーを変数にすることができるので(2)の問題も消える

 import pickle
import numpy as np

def pickle_vars(fname, mode='wb', **vars):
	# **varsは可変長のキーワード引数
	dic = {}
	for key in vars.keys():
		exec('dic[key]=vars.get(key)')

	with open(fname, mode) as f:
		pickle.dump(dic, f)

	return dic


if __name__ == '__main__':
	a = np.float(2.3)
	b = np.array([[1.1, 2.2, 3.3], [4.4, 5.5, 6.6]])
	c = {'yokohama':1, 'tokyo':2, 'nagoya':3}

	saved_dat = pickle_vars('pickle1.pickle', a=a, b=b, c=c)

	with open('pickle1.pickle', 'rb') as f:
		dat = pickle.load(f)
		for key in dat.keys():
			exec(key+'=dat.get(key)')

npy, npz形式

npy/npzはnumpyのデータを保存するためのもの.
npyはひとつのnumpyオブジェクトを保存する時に使用して, npzは複数のnumpyオブジェクトを保存する時に利用する. 以下に実際のコードをみていく

import numpy as np

a = np.array([1, 2, 3])
np.save('foo', a)

#ひとつのnumpyオブジェクトの場合, 自動的にnpyに変換される
a = np.load('foo.npy')

#npzは複数のnumpyオブジェクトの時に利用
b = np.array([1, 2], [3, 4])
np.savez('foo.npz', a=a, b2=b)

with np.load('foo.npz') as data:
   a2 = data['a']
   b2 = data['b2']

HDF5形式

データを階層構造にして保存することができる形式
実際にコードを見たほうが早い

import h5py
import numpy as np

t = np.arange(0, 5, 0.1)
y = np.sin(2*np.pi*0.3*t)
dist = [2, 5, 1, 3, 8, 9, 12]

with h5py.File('data1.h5', 'w') as f:
    f.create_group('wave')
    f.create_dataset('wave/t', data=t)
    f.create_dataset('wave/y', data=y)
    f.create_dataset('dist', data=dist)

#データの読み出し
with h5py.File('data1.h5', 'r') as f:
    t = np.array(f['wave/t'])
    y = np.array(f['wave/y'])
    dist = np.array(f['dist'])