基本問題是,NumPy不理解剝離引號的概念(而csv
模塊)。當你說delimiter='","'
時,你告訴NumPy,列分隔符實際上是一個帶引號的逗號,即引號是在逗號周圍,而不是值,因此可以期望獲得第一列和最後一列的額外引號。
綜觀功能的文檔,我想你會需要設置converters
參數剝離報價爲您(默認沒有):
import re
import numpy as np
fieldFilter = re.compile(r'^"?([^"]*)"?$')
def filterTheField(s):
m = fieldFilter.match(s.strip())
if m:
return float(m.group(1))
else:
return 0.0 # or whatever default
#...
# Yes, sorry, you have to know the number of columns, since the NumPy docs
# don't say you can specify a default converter for all columns.
convs = dict((col, filterTheField) for col in range(numColumns))
data = np.genfromtxt(csvfile, dtype=None, delimiter=',', names=True,
converters=convs)
或放棄np.genfromtxt()
讓csv.csvreader
給你文件的內容排在同一時間,作爲字符串列表,那麼你只需要通過迭代的元素,並建立矩陣:
reader = csv.csvreader(csvfile)
result = np.array([[float(col) for col in row] for row in reader])
# BTW, column headings are in reader.fieldnames at this point.
編輯:好的,所以它看起來像你的文件是不是所有的花車。在這種情況下,你可以設置convs
根據需要在genfromtxt
情況下,或者在csv.csvreader
情況下創建的轉換函數的向量:
reader = csv.csvreader(csvfile)
converters = [datetime, float, int, float]
result = np.array([[conv(col) for col, conv in zip(row, converters)]
for row in reader])
# BTW, column headings are in reader.fieldnames at this point.
編輯2:好,可變列數...您的數據源只是想讓生活變得困難。幸運的是,我們可以使用magic
...
reader = csv.csvreader(csvfile)
result = np.array([[magic(col) for col in row] for row in reader])
...其中magic()
只是一個名字,我得到了我的頭一個函數的頂部。 (!琪)
在最壞情況下,它可能是這樣的:
def magic(s):
if '/' in s:
return datetime(s)
elif '.' in s:
return float(s)
else:
return int(s)
也許NumPy的具有如下功能:接受一個字符串,並返回正確類型的單個元素。 numpy.fromstring()
看起來很接近,但它可能會將時間戳中的空格解釋爲列分隔符。
P.S. csvreader
我看到的一個缺點是它不放棄評論;真實csv
文件沒有評論。
如果輸入文件很大(很多MB或GB),'str.replace(''','')'方法的執行速度應該比正則表達式快得多,如果你能假設'' '字符不會出現在字段的中間,只在末尾出現。 – gotgenes 2010-04-19 02:29:28
感謝Mike和gotgenes,但我也應該提到CSV文件具有可變數量的列。我可以使用上面描述的方法,通過添加一個初始步驟來讀取文件的第一個記錄來確定列的數量,然後將它用作後面步驟的輸入,但它看起來非常笨重。 有沒有更好的方法? – monch1962 2010-04-19 02:46:57
小注:你不需要使用're.compile()',因爲直接使用re.match()直接緩存已編譯的正則表達式。 – blokeley 2010-04-19 07:42:18