ファイルを numpy マトリックスに読み込みたいと思います。このファイルでは、各行は「行;列;値」の構造を持っているため、次のような行列
m = numpy.matrix([[1,2,3],[4,5,6]])
次の行で始まるファイルになります。
0;0;1
0;1;2
0;2;3
1;0;4
...
Numpy でそのようなファイルを読み込んで保存する方法が組み込まれていないことがわかりました。手動で行うと非常に遅くなる可能性があります。どの方法をお勧めしますか?
組み込みの方法はありません。コメントで指摘されているように、形状を保存してからマトリックスのフラットな 1D バージョンを保存する方がはるかに高速です。ただし、マトリックスが巨大でない限り、手動で行うことは大きなボトルネックにはなりません。これを行うには多くの方法があります。次の例を使用しnumpy.nditer
ます。
m = np.matrix([[1,2,3],[4,5,6]])
f = open('output.txt', 'w')
it = np.nditer(m, flags=['multi_index'])
while not it.finished:
f.write('%i;%i;%i\n' % (it.multi_index[0], it.multi_index[1], it[0]))
it.iternext()
これにより、次のようになります。
0;0;1
0;1;2
0;2;3
1;0;4
1;1;5
1;2;6
これらの変換を行ういくつかの単純な関数を作成できます。
def to_ijv(a):
rows, cols = a.shape
ijv = np.empty((a.size,), dtype=[('i', np.intp),
('j', np.intp),
('v', a.dtype)])
ijv['i'] = np.repeat(np.arange(rows), cols)
ijv['j'] = np.tile(np.arange(cols), rows)
ijv['v'] = a.ravel()
return ijv
def from_ijv(ijv):
rows, cols = np.max(ijv['i']) + 1, np.max(ijv['j']) + 1
a = np.empty((rows, cols), dtype=ijv['v'].dtype)
a[ijv['i'], ijv['j']] = ijv['v']
return a
行列が大きい場合は、組み込みのloadtxt
andsavetxt
を使用してディスクの読み取りと書き込みを行うことができます。
def save_ijv(file_, a):
ijv = to_ijv(a)
np.savetxt(file_, ijv, delimiter=';', fmt=('%d', '%d', '%f'))
def read_ijv(file_):
ijv = np.loadtxt(file_, delimiter=';',
dtype=[('i', np.intp),('j', np.intp),
('v', np.float)])
return from_ijv(ijv)
これらの関数は浮動小数点数を好むため、例えば整数が必要な場合は、フォーマットを明示的に編集する必要があります。それ以外はうまく機能します:
>>> a = np.arange(1, 7).reshape(3, 2)
>>> a
array([[1, 2],
[3, 4],
[5, 6]])
>>> to_ijv(a)
array([(0L, 0L, 1), (0L, 1L, 2), (1L, 0L, 3), (1L, 1L, 4), (2L, 0L, 5),
(2L, 1L, 6)],
dtype=[('i', '<i8'), ('j', '<i8'), ('v', '<i4')])
>>> import StringIO as sio
>>> file_ = sio.StringIO()
>>> save_ijv(file_, a)
>>> print file_.getvalue()
0;0;1.000000
0;1;2.000000
1;0;3.000000
1;1;4.000000
2;0;5.000000
2;1;6.000000
>>> file_.pos = 0
>>> b = read_ijv(file_)
>>> b
array([[ 1., 2.],
[ 3., 4.],
[ 5., 6.]])