Python 从文本文件到市场矩阵格式

Python 从文本文件到市场矩阵格式,python,matrix,sparse-matrix,Python,Matrix,Sparse Matrix,我在Python中工作,我有一个存储在文本文件中的矩阵。文本文件的排列格式如下: 行id,列id行id,列id行id,列id行id,列id row_id和col_id是整数,取值范围从0到n(为了知道row_id和col_id的n,我必须先扫描整个文件) 文件中没有头、行和列id,列id在文件中出现多次,但每个组合行id、列id出现一次。每个组合行id、列id没有显式值,实际上每个单元格的值都是1。该文件的大小几乎为1GB 不幸的是,该文件很难在内存中处理,事实上,26622704个元素的行ID

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

行id,列id
行id,列id
行id,列id
行id,列id

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

文件中没有头、行和列id,列id在文件中出现多次,但每个组合行id、列id出现一次。每个组合行id、列id没有显式值,实际上每个单元格的值都是1。该文件的大小几乎为1GB

不幸的是,该文件很难在内存中处理,事实上,26622704个元素的行ID为2257205,列ID为122905。所以我在寻找更好的方法来处理它。矩阵市场模式可能是解决这一问题的一种方法


有没有一种快速且内存高效的方法可以使用Python将此文件转换为市场矩阵格式的文件?

有一种快速且内存高效的方法可以处理此类矩阵:使用(这是Python中用于此类事情的事实标准)

对于大小为
N
by
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

split()
的参数
1
在这里只是为了在解析坐标时加快速度:它指示Python在找到第一个(也是唯一一个)逗号时停止解析该行。这可能会有些影响,因为您正在读取1 GB的文件

根据您的需要,您可能会发现SciPy提供的其中一个更适合您


如果您想要一个速度更快但占用内存更多的数组,可以使用
result=numpy.array(…)
(使用numpy)来代替。

除非我遗漏了什么

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

在中简单地使用sed不是更容易吗

n=`wc -l file`
echo "2257205 122905 $n" > file.mm
cat file | sed -e 's/$/ 1/g' >> file.mm
如果你的坐标是一个偏移量,那就行了。如果偏移量为零,则应向每个坐标添加+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

还是我遗漏了什么?

行。拆分(“,”,1)是个好主意!非常感谢。事实上,我一开始已经尝试过lil_matrix,速度很快,但很快就遇到了内存错误。因此,我转向csc_矩阵,但以这种数据格式加载值的速度非常慢。如果矩阵元素不改变,保持0和1,则存储布尔值或整数而不是浮点值应该可以节省空间。我在代码中添加了这样的注释。文档还推荐了
dok_矩阵
:您尝试过吗?更一般地说,我认为没有什么比尝试多个稀疏矩阵表示并检查最适合您的表示更好的了。非常感谢您的建议,我找到了解决问题的方法。太好了。你能分享吗?这将帮助别人!由于每个逻辑单元值要么为空,要么为1,因此该矩阵本质上是一个2D位图。由于Python支持任何大小的整数值,因此您可以将矩阵作为整数列表存储在内存中,并可以通过查找和少量位操作确定任何单元格的值。行和列ID的上限是什么?行的上限是225705,列的上限是122905。表示该大小的位图需要大约32 GB,太大而无法存储在内存中。它可以存储在二进制文件中。太访问位[row][col]需要计算包含该位的字节,寻找该文件偏移量,并读取或写入一个字节。对于26622704个元素,这将需要大量的文件IO,但听起来是可行的。