3

我在 Python 中工作,我有一个存储在文本文件中的矩阵。文本文件以这样的格式排列:

row_id, col_id
row_id, col_id
...
row_id, col_id

row_id 和 col_id 是整数,它们取值从 0 到 n(为了知道 row_id 和 col_id 的 n,我必须先扫描整个文件)。

文件中没有标题,row_ids 和 col_ids 出现多次,但每个组合 row_id,col_id 出现一次。每个组合 row_id,col_id 没有明确的值,实际上每个单元格的值为 1。该文件几乎是 1 GB 大小。

不幸的是,该文件在内存中很难处理,实际上,对于 26622704 个元素,它是 2257205 row_ids 和 122905 col_ids。所以我一直在寻找更好的方法来处理它。矩阵市场形式可能是处理它的一种方式。

是否有一种快速且内存有效的方法可以使用 Python将此文件转换为市场矩阵格式(http://math.nist.gov/MatrixMarket/formats.html#mtx )的文件?

4

2 回答 2

6

有一种处理此类矩阵的快速且内存高效的方法:使用SciPy 提供的稀疏矩阵(这是 Python 中此类事物的事实上的标准)。

对于大小为 的N矩阵N

from scipy.sparse import lil_matrix

result = lil_matrix((N, N))  # In order to save memory, one may add: dtype=bool, or dtype=numpy.int8

with open('matrix.csv') as input_file:
    for line in input_file:
        x, y = map(int, line.split(',', 1))  # The "1" is only here to speed the splitting up
        result[x, y] = 1

(或者,一行而不是两行:)result[map(int, line.split(',', 1))] = 1

1给出的参数split()只是为了在解析坐标时加快速度:它指示 Python 在找到第一个(也是唯一的)逗号时停止解析行。这可能很重要,因为您正在阅读一个 1 GB 的文件。

根据您的需要,您可能会发现SciPy 提供的其他六种稀疏矩阵表示之一更适合。

如果你想要一个更快但也更消耗内存的数组,你可以使用result = numpy.array(…)(with NumPy) 代替。

于 2013-06-15T09:06:51.763 回答
2

除非我错过了什么……

MatrixMarket MM 格式是一条带有尺寸和“行列值”的线。如果您已经有行和列并且所有值都是 1,只需添加该值即可。

像这样简单地使用 sed 不是更容易吗

n=`wc -l file`
echo "2257205 122905 $n" > file.mm
cat file | sed -e 's/$/ 1/g' >> file.mm

如果您的坐标是单偏移的,那应该可以工作。如果它们是零偏移量,则应为每个坐标添加 +1,只需读取坐标,为每个坐标添加 1 并打印 coordx, coordy, "1"。您可以通过 shell、Awk 或 python 轻松完成。

Q&D 代码(未经测试,仅作为提示生成,YMMV,您可能希望对文件进行预处理以计算一些值):

在壳里

echo "2257205 122905 $n"
cat file | while read x,y ; do x=$((x+1)); y=$((y+1)); echo "$x $y 1" ; done

在python中,或多或少...

f=open("file")
lines=f.readlines()
print 2257205, 122905, len(lines)
for l in lines:
    (x,y) = l.split(' ')
    x = int(x) + 1
    y = int(y) + 1
    print x, y, 1

还是我错过了什么?

于 2015-11-12T09:31:07.937 回答