从大文本文件到Python的稀疏矩阵

时间:2014-04-03 13:33:23

标签: python text sparse-matrix

我试图找到一种有效的方法来读取一个非常大的文本文件(大约2,000,000行)。这些行中约有90%(实际上最后90%)具有三列格式,用于存储稀疏矩阵。

这就是我所做的。首先,我处理文件的前10%:

i=1
cpt=0
skip=0
finnum=0
indice=1 
vec=[]
mat=[]
for line in fileinput.input("MY_TEXT_FILE.TXT"):
if i==1:
    # skipping the first line
    skip = 1
if (finnum == 0)and(skip==0):
    # special reading operation for the first 10% (approximately)
    tline=shlex.split(line)
    ind_loc=0
    while ind_loc<len(tline):
    if (int(tline[ind_loc])!=0):
            vec.append(int(tline[ind_loc]))
        ind_loc=ind_loc+1   
if (finnum == 1)and(skip==0):
    print('finnum = 1')
    h=input()    
        break       
    if (' 0' in line):
    finnum = 1
if skip == 0:
    i=i+1
else:
    skip=0
    i=i+1
cpt=cpt+1

然后我将剩下的90%提取到一个列表中:

matrix=[]
with open('MY_TEXT_FILE.TXT') as f:
for i in range(cpt):
    f.next()
for line in f:
    matrix.append(line)

这允许以非常低的内存消耗快速读取文本文件。缺点是矩阵是一个字符串列表,每个字符串类似于:

>>> matrix[23]
'           5          11  8.320234929063493E-008\n'

我尝试在矩阵的行上使用迭代过程,并结合 shlex.split 命令从字符串列表转到数组,但这是非常耗时。

您是否了解从字符串列表到数组的快速策略?

我想知道的是,如果有比这个程序更快的东西:

A=[0]*len(matrix)
B=[0]*len(matrix)
C=[0]*len(matrix)
for i in range(len(matrix)):
     line = shlex.split(matrix[i])
     A[i]=float(line[0])
     B[i]=float(line[1])
     C[i]=float(line[2])

阿兰

2 个答案:

答案 0 :(得分:2)

当您处理大量数值数据时,您应该使用Numpy,而不是使用纯python。这通常会快10倍以上,并且您可以访问Matlab风格的复杂计算。我现在没有时间转换您的代码(并且最简单的是拥有示例文件),但是使用numpy.loadtxt可以快速有效地阅读文件的第二部分。跳过第一部分并转换为float的代码的第二部分可能是这样的:

A, B, C = np.loadtxt('MY_TEXT_FILE.TXT', skiprows = cpt, unpack = True)

您可能想要使用数据格式(通过添加dtype = (int, int, float)左右,不确切知道如何执行此操作),因为我猜前两列是整数。

另请注意,numpy具有sparse matrix数据类型。

答案 1 :(得分:2)

看,我想出了这种混合解决方案似乎更快。我创建了一个100万个样本随机数据,就像你上面提到的那样,并为你的代码计时。我的Mac电脑花了77秒,顺便说一句,这是一台超快速的电脑。 使用numpy来分割字符串而不是shlex最终会在5秒的处理过程中结束。

A=[0]*len(matrix)
B=[0]*len(matrix)
C=[0]*len(matrix)
for i in range(len(matrix)):
    full_array = np.fromstring(matrix[i], dtype=float, sep=" ")
    A[i]=full_array[0]
    B[i]=full_array[1]
    C[i]=full_array[2]

我做了几个测试,看起来效果很好,而且速度提高了14倍。 我希望它有所帮助。