我想读取一个只包含数值(带小数)的csv格式的文件并将其存储在矩阵中,以便我可以对它们执行操作。该文件如下所示:
1.5,2.3,4.4
1.1,5.3,2.4
...
它可能包含数千行和超过3列。
我使用go csv库解决了这个问题。这会创建一个 [] []字符串,然后我使用for循环将矩阵解析为 [] [] float64 。
func readCSV(filepath string) [][]float64 {
csvfile, err := os.Open(filepath)
if err != nil {
return nil
}
reader := csv.NewReader(csvfile)
stringMatrix, err := reader.ReadAll()
csvfile.Close()
matrix := make([][]float64, len(stringMatrix))
//Parse string matrix into float64
for i := range stringMatrix {
matrix[i] = make([]float64, len(stringMatrix[0]))
for y := range stringMatrix[i] {
matrix[i][y], err = strconv.ParseFloat(stringMatrix[i][y], 64)
}
}
return matrix
}
我想知道这是否是一种正确有效的方法,或者是否有更好的方法。
比如使用reader.Read()代替并在读取时解析每一行。我不知道,但感觉我做了很多重复的工作。
答案 0 :(得分:4)
这完全取决于您希望如何使用数据。您的代码在内存方面效率不高,因为您在内存中读取了整个CSV内容(stringMatrix
),然后创建另一个变量来保存转换为float64(matrix
)的数据。因此,如果您的CSV文件大小为1 GB,那么您的程序将stringMatrix
使用1 GB的RAM + matrix
更多。
您可以通过以下方式优化代码:
reader
并将数据附加到matrix
;你不需要一次把整个stringMatrix
留在记忆中; reader
并逐行处理该数据。也许你不需要在内存中拥有matrix
,也许你可以在阅读时处理数据,并且不会在内存中同时拥有所有内容。这取决于程序的其余部分,以及它如何使用CSV数据。如果您不使用上述第二种方法,如果您不需要从该功能返回整个CSV数据,您的程序可以使用几个字节的RAM而不是千兆字节。