2013-07-29 39 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

素晴らしいですが、魅力のように動作します。私は「パンダ」について少し聞いたことがあるが、これまでに試してみることは一度もなかった。これは素晴らしい機会のようだ。そして、私は初期の例を単純にしていましたが、実際には構造化されたnumpy配列を得るために 'np.recfromcsv'を使う予定でした。 – CraigO

9

追加のカンマの問題は、np.genfromtxtには該当しません。

単純な解決策の1つは、csv.reader()のファイルをPythonのcsvモジュールからリストに読み込んでリストに入れ、それを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() 

パンダは標準csv moduleの力を組み合わせ、numpyののrecfromcsv優れた機能を確認し、正しく

+0

これを行うと、最初の行が失われる可能性があることに注意してください。最初の行は、データフレームの列ラベルとして扱われます。 –

1

「レキシントン、KY」ケースを処理します。たとえば、csvモジュールでは、方言、引用符、エスケープ文字などを適切に制御しカスタマイズすることができます。これを下の例に追加することができます。

以下の例のgenfromcsv_modは、Microsoft Excelと同様の複雑なCSVファイルを読み込みます。引用されたフィールドにカンマが含まれている可能性があります。内部的には、この関数には各行をタブデリミタで書き換えるジェネレータ関数があります。

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) 
関連する問題