在go中导入数字csv数据的正确方法

时间:2017-09-14 17:48:34

标签: csv go

我想读取一个只包含数值(带小数)的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()代替并在读取时解析每一行。我不知道,但感觉我做了很多重复的工作。

1 个答案:

答案 0 :(得分:4)

这完全取决于您希望如何使用数据。您的代码在内存方面效率不高,因为您在内存中读取了整个CSV内容(stringMatrix),然后创建另一个变量来保存转换为float64(matrix)的数据。因此,如果您的CSV文件大小为1 GB,那么您的程序将stringMatrix使用1 GB的RAM + matrix更多。

您可以通过以下方式优化代码:

  • 逐行阅读reader并将数据附加到matrix;你不需要一次把整个stringMatrix留在记忆中;
  • 逐行阅读reader并逐行处理该数据。也许你不需要在内存中拥有matrix,也许你可以在阅读时处理数据,并且不会在内存中同时拥有所有内容。这取决于程序的其余部分,以及它如何使用CSV数据。

如果您不使用上述第二种方法,如果您不需要从该功能返回整个CSV数据,您的程序可以使用几个字节的RAM而不是千兆字节。