1. 程式人生 > >如何高效讀取CSV檔案後進行高效處理?(之一:高效讀取CSV格式檔案)

如何高效讀取CSV檔案後進行高效處理?(之一:高效讀取CSV格式檔案)

背景簡介:

現有一個資料夾,全部是CSV格式檔案。需要從這些CSV檔案中逐一讀取第一列,取前100個和後100個組成一個二維陣列,最終將這些二維數組合併成一個大的二維陣列

問題解剖

可以把問題分成三大部分:

  1. 逐一讀取CSV格式檔案的第一列;
  2. 對每個CSV檔案進行處理(取前100個和後100個,合併);
  3. 對上一步獲得的的二維陣列進行合併。

問題分析

問題一: (逐一)讀取CSV格式檔案

考慮到實際情況,可以以一個CSV檔案為例進行說明。逐一讀取多個同一路徑下的檔案可以考慮使用glob模組的iglob方法,這裡不廢話。
目前,Python3(以下簡稱Python)至少有三種辦法讀取CSV格式檔案,分別是:

1.csv模組
2.numpy裡面的loadtxt方法
3.pandas裡面的read_csv方法

這裡採用time模組裡的timeit計時模組,測試機器的CPU為i7 6820HQ,16G記憶體,搭載windows10 64位系統。
由於csv.reader方法是把每一行資料轉化成了一個list,list中每個元素是一個字串,並不能(或者說很難)滿足我們的需求(可以間接實現我們的需求,後面有機會再補充),因而這裡只比較numpy模組的方法和pandas模組的方法。由於pandas方法效率比較高,故而增加pandas模組讀取後轉存為numpy.ndarray格式檔案的測試。
測試程式碼塊示例如下:

import timeit

import numpy
import pandas

def func_numpy():
    filepath = r'csv filepath'
    numpy.loadtxt(filepath, usecols=[0], delimiter=',')

def func_pandas():
    filepath = r'csv filepath'
    pandas.read_csv(filepath, usecols=[0])

def fun_pandas2numpy():
    filepath = r'csv filepath'
    pandas.read_csv(filepath, usecols=[0
]).as_matrix() # 開始計時 t_numpy = timeit.timeit('func_numpy()', 'from __main__ import func_numpy', number=100) t_pandas = timeit.timeit('func_pandas()', 'from __main__ import func_pandas', number=100) t_pandas2numpy = timeit.timeit('fun_pandas2numpy()', 'from __main__ import fun_pandas2numpy', number=100) print('讀取100次,numpy模組loadtxt方法用時:', t_numpy) print('讀取100次,pandas模組read_csv方法用時:', t_pandas) print('讀取100次,pandas模組read_csv方法讀取後並將其轉化為ndarray格式檔案用時:', t_pandas2numpy)

執行結果如下:

讀取100次,numpy模組loadtxt方法用時: 75.16465592171689

讀取100次,pandas模組read_csv方法用時: 6.334802627057911

讀取100次,pandas模組read_csv方法讀取後並將其轉化為ndarray格式檔案用時: 5.922901347888825

需要指出的是pandas模組read_csv方法和pandas模組read_csv方法讀取後並將其轉化為ndarray格式檔案的前後順序對執行結果會有影響(哪個在前面哪個的時間會略慢,請大佬批評指正)。但是這兩種方法相比較numpy方法而言,差距並不是很大。

因而:

更推薦使用pandas模組裡的read_csv方法,如果需要將資料儲存為numpy.ndarray格式檔案,可以選擇在後面使用pandas.DataFrame.as_matrix()方法

Reference: