Numpy加载并保存ijv(行列值)格式

时间:2013-03-30 11:41:35

标签: matrix numpy

我想把文件读成一个numpy矩阵。在这个文件中,每一行都有结构“row; col; value”,所以像

这样的矩阵
m = numpy.matrix([[1,2,3],[4,5,6]])

将位于以下行开头的文件中:

0;0;1
0;1;2
0;2;3
1;0;4
...

我没有找到在Numpy中加载和保存这些文件的内置方法,手动执行此操作可能会非常慢。你会建议哪种方式?

2 个答案:

答案 0 :(得分:2)

没有内置方式。正如评论中指出的那样,保存形状然后是矩阵的平面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

答案 1 :(得分:1)

您可以构建一些简单的函数来执行这些转换:

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

如果您的矩阵很大,您可以使用内置的loadtxtsavetxt来读取和写入磁盘:

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.]])