这是《机器学习in Action》第2章中的一段代码。 目标是将文件传输到matix。我不明白的是为什么我应该两次使用fr = open(filename)?
当我删除第二个open(filename)时,代码仅返回空白矩阵。我不知道为什么。
非常感谢您抽出宝贵的时间!
def file2matrix(filename):
fr = open(filename)
numberOfLines = len(fr.readlines())
returnMat = zeros((numberOfLines,3))
classLabelVector = []
fr = open(filename)
index = 0
for line in fr.readlines():
line = line.strip()
listFromLine = line.split('\t')
returnMat[index,:] = listFromLine[0:3]
classLabelVector.append(int(listFromLine[-1]))
index += 1
return returnMat,classLabelVector
答案 0 :(得分:1)
它将读取文件两次:
首先读取所有行,然后对行进行计数并初始化矩阵:
fr = open(filename)
numberOfLines = len(fr.readlines())
returnMat = zeros((numberOfLines,3))
其次,它再次读取文件以填充矩阵:
fr = open(filename)
index = 0
for line in fr.readlines():
line = line.strip()
...
它需要再次打开文件,以便从头开始重新读取。
这不是有效的代码。由于fr.readlines()
会读取整个文件,因此无需再次读取文件,而是将结果(行列表)存储在变量中,并在填充矩阵时重新使用。
完成文件处理后,还应该调用close()
。
答案 1 :(得分:1)
使用readlines函数时,它将所有行读入内存,并且在文件末尾,文件指针位于文件的末尾。
因此,如果您已经使用完后尝试重新读取行,由于文件指针位于末尾,它将从头到尾读取,因此为空白矩阵。
他们重新打开了文件,以便文件指针从头开始。这样做的另一种方法是filevariable.seek(0),它将文件指针移回起点,您应该能够再次使用读取行。
要注意的一件事是,readlines会将整个文件读入内存,如果您有一个庞大的文件,则应使用for循环并使用readline一次读取一行。
答案 2 :(得分:0)
现在建议在处理文件时始终使用上下文管理器。请尝试以下操作,它应该与您要寻找的非常接近。
def file2matrix(filename):
with open(filename, "r") as fr:
returnMat = zeros((len(fr.readlines,3))
classLabelVector = []
index = 0
for line in fr:
line = line.strip()
listFromLine = line.split('\t')
returnMat[index,:] = listFromLine[0:3]
classLabelVector.append(int(listFromLine[-1]))
index += 1
return returnMat,classLabelVector