2013-07-29 81 views
21

我想讀取與numpy.genfromtxt的csv文件,但某些字段是包含逗號的字符串。字符串用引號引起來,但numpy不能將引號識別爲定義單個字符串。例如,在 't.csv' 中的數據:使用numpy.genfromtxt讀取包含逗號的字符串的csv文件

2012, "Louisville KY", 3.5 
2011, "Lexington, KY", 4.0 

代碼

np.genfromtxt('t.csv', delimiter=',') 

產生錯誤:

ValueError: Some errors were detected ! Line #2 (got 4 columns instead of 3)

的數據結構我尋找是:

array([['2012', 'Louisville KY', '3.5'], 
     ['2011', 'Lexington, KY', '4.0']], 
     dtype='|S13') 

查看文檔,我沒有看到任何處理這個問題的方案。有沒有辦法做到numpy,還是我只需要用csv模塊讀取數據,然後將其轉換爲numpy數組?

+0

您可以發佈更完整的CSV,我想我知道如何解決你的問題;) –

+0

您應該改變您的CSV從'替換分隔符,''來;'例如... –

+0

@SaulloCastro:我不能這樣做,因爲我的真實數據非常混亂,並且帶有';'和/或任何其他可以想到的角色的字符串 - 這僅僅是一個玩具的例子。我正在尋找的是更通用的解決方案。 – CraigO

回答

17

您可以使用pandas(成爲科學python中的數據框(異構數據)的默認庫)。這是read_csv可以處理這個。從文檔:

quotechar : string

The character to used to denote the start and end of a quoted item. Quoted items 
can include the delimiter and it will be ignored. 

默認值是"。舉個例子:

In [1]: import pandas as pd 

In [2]: from StringIO import StringIO 

In [3]: s="""year, city, value 
    ...: 2012, "Louisville KY", 3.5 
    ...: 2011, "Lexington, KY", 4.0""" 

In [4]: pd.read_csv(StringIO(s), quotechar='"', skipinitialspace=True) 
Out[4]: 
    year   city value 
0 2012 Louisville KY 3.5 
1 2011 Lexington, KY 4.0 

這裏的技巧是,你還可以選擇使用skipinitialspace=True應對逗號分隔後的空間。

除了一個功能強大的csv閱讀器,我還可以強烈建議您使用帶有異構數據的熊貓(儘管您可以使用結構化數組,但您提供的numpy示例輸出都是字符串)。

+0

太棒了,就像一個魅力。我聽說過一些關於'熊貓'的消息,但從未嘗試過 - 這似乎是一個很好的機會。順便說一下,我試圖保持我的初始示例簡單,但實際上我打算使用'np.recfromcsv'來獲得結構化的numpy數組。 – CraigO

9

問題與其他逗號np.genfromtxt不處理。

一個簡單的解決方案是從Python的csv模塊csv.reader()文件中讀取到一個列表,然後將其轉儲到numpy的數組,如果你喜歡。

如果您確實想使用np.genfromtxt,請注意,它可以使用迭代器而不是文件,例如, np.genfromtxt(my_iterator, ...)。因此,您可以將csv.reader包裝在迭代器中,並將其提供給np.genfromtxt

那會去是這樣的:

import csv 
import numpy as np 

np.genfromtxt(("\t".join(i) for i in csv.reader(open('myfile.csv'))), delimiter="\t") 

這基本上將替換即時只與標籤相應的逗號。

+0

嗯,我看到你在這裏得到了什麼,但我玩了一下,但仍然無法讓它工作得很好。無論如何,我認爲今天我要用'熊貓'路線。不管怎麼說,還是要謝謝你。 – CraigO

3

如果您使用的是numpy,那麼您可能需要使用numpy.ndarray。這會給你一個numpy.ndarray:

import pandas 
data = pandas.read_csv('file.csv').as_matrix() 

大熊貓將處理「列剋星敦」的情況下正確

+0

請注意,如果您這樣做,第一行可能會丟失。第一行被視爲數據框的列標籤。 –

1

創造一個更美好的功能,結合了標準csv module的功率和NumPy的的recfromcsv。例如,csv模塊可以很好地控制和定製方言,引號,轉義字符等,您可以添加到下面的示例中。

示例genfromcsv_mod函數讀取類似於Microsoft Excel所見的複雜CSV文件,該文件可能在引用字段中包含逗號。在內部,函數有一個生成器函數,用tab分隔符重寫每一行。

import csv 
import numpy as np 

def recfromcsv_mod(fname, **kwargs): 
    def rewrite_csv_as_tab(fname): 
     with open(fname, 'rb') as fp: 
      reader = csv.reader(fp) 
      for row in reader: 
       yield '\t'.join(row) 
    return np.recfromcsv(rewrite_csv_as_tab(fname), delimiter='\t', **kwargs) 

# Use it to read a CSV file into a record array 
x = recfromcsv_mod('t.csv', case_sensitive=True) 
相關問題