2017-09-14 35 views
0

我想讀取僅包含數值(帶小數)的csv格式的文件並將其存儲在矩陣中,以便我可以對它們執行操作。該文件是這樣的:正確導入數字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()相反,並在讀取時解析每一行。我不知道,但感覺我正在做很多重複的工作。

回答

5

這一切都取決於你想如何使用數據。您的代碼在內存方面效率不高,因爲您讀取了內存中的整個CSV內容(stringMatrix),然後創建另一個變量來保存轉換爲float64的數據(matrix)。因此,如果您的CSV文件的大小爲1 GB,則您的程序將使用1 GB的內存作爲stringMatrix +更多用於matrix

,可以優化通過任一的代碼:

  • reader逐行和數據附加到matrix;你不需要一次將所有的stringMatrix存儲在內存中;
  • 逐行讀取reader並逐行處理該數據。也許你不需要在內存中有matrix,也許你可以在閱讀時處理數據,並且不會一次在內存中擁有所有內容。這取決於您的程序的其餘部分,以及如何使用CSV數據。

如果您使用上面的第二種方法,如果您不需要從該函數返回完整的CSV數據,則您的程序可以使用幾個字節的RAM而不是千兆字節。