Python Pandas Errorデータのトークン化


341

パンダを使用して.csvファイルを操作しようとしていますが、次のエラーが発生します。

pandas.parser.CParserError:データのトークン化エラー。Cエラー:3行目に2つのフィールドが必要ですが、12を見ました

パンダのドキュメントを読み込もうとしましたが、何も見つかりませんでした。

私のコードは単純です:

path = 'GOOG Key Ratios.csv'
#print(open(path).read())
data = pd.read_csv(path)

どうすればこれを解決できますか?csvモジュールまたは別の言語を使用する必要がありますか?

ファイルはMorningstarからのものです


10
によって書き込まれたファイルを読み取るときにこのエラーが発生する場合pandas.to_csv()、列名に「\ r」があるためである可能性があります。この場合、to_csv()は実際に後続の列名をデータフレームの最初の列に書き込み、最初のX行の列数の違い。この違いは、Cエラーの原因の1つです。
user0 2017年

8
「sep」パラメータを明示的に指定すると役立つ場合があります。パーサーの問題のようです。
ギルガマッシュ2018年

2
このエラーは、区切り文字としてコンマを使用していて、予想されるより多くのコンマがある場合にも発生する可能性があります(エラー行のフィールドが増えて、ヘッダーで定義されます)。したがって、追加のフィールドを削除するか、誤ってそこにある場合は余分なコンマを削除する必要があります。これは手動で修正でき、エラー行をスキップする必要はありません。
tsveti_iko 2018

2
gilgamashからのコメントは私を助けました。テキストエディター(windowsエディターやnotepad ++など)でcsvファイルを開き、どの文字が分離に使用されているかを確認します。セミコロンの場合は、たとえばを試してくださいpd.read_csv("<path>", sep=";")。チェックにExcelを使用しないでください。デフォルトでデータが列に入れられ、セパレータが削除されることがあります。
ジュリアン

@gilgamashのコメントについて-これは正しい方向に私を送りましたが、私の場合、「sep」パラメータを明示的に指定しないことで解決されました。
TheLoneDeranger

回答:


514

あなたも試すことができます。

data = pd.read_csv('file1.csv', error_bad_lines=False)

これにより、問題の行がスキップされることに注意してください。


151
error_bad_lines = Falseを使用すると、問題の行がスキップされることに注意してください。
biobirdman 2014年

10
この答えにつまずいたのですが、行の欠落している列を埋める方法はありexpected 8 fields, saw 9ますか?
Petra Barus 2014

26
より良い解決策は、問題のあるファイルを調査し、不良行を修正して、それらがで読み取れるようにすることread_csvです。@PetraBarus、欠落している(必要に応じてnull値を含む)CSVファイルに列を追加しないのはなぜですか?
dbliss 2014年

4
はい、私はちょうどそれをやった。列を追加すると、はるかに簡単になります。スプレッドシートでCSVを開くとこれが行われます。
Petra Barus 2014年

5
names=["col1", "col2", ...]予想される列の最大数を渡すことも機能します。これが、この問題に遭遇したときに解決した方法です。参照:stackoverflow.com/questions/18039057/...
スティーブンRouk

99

それは問題かもしれません

  • データ内の区切り文字
  • @TomAugspurgerが述べたように、最初の行

これを解決するには、を呼び出すときにsepheader引数を指定してみてくださいread_csv。例えば、

df = pandas.read_csv(fileName, sep='delimiter', header=None)

上記のコードでsepは、区切り文字を定義header=Noneし、ソースデータにヘッダー/列タイトルの行がないことをパンダに伝えます。したがって、ドキュメントによると「ファイルにヘッダー行が含まれていない場合は、header = Noneを明示的に渡す必要があります」。この例では、パンダは各フィールド{0,1,2、...}に対して整数インデックスを自動的に作成します。

ドキュメントによると、区切り文字は問題になりませ。ドキュメントは、「sepがNone [指定されていない]の場合、これを自動的に判断しようとする」と述べています。しかし、明らかな区切り文字のあるインスタンスを含め、私はこれでうまくいきませんでした。


はい、区切り文字がこの問題の原因になる場合があります。区切り文字がセミコロン(;)であるのと同じ問題に直面しました
Anurag Sharma

43

パーサーは、ファイルのヘッダーによって混乱しています。最初の行を読み取り、その行から列数を推測します。ただし、最初の2行はファイル内の実際のデータを表していません。

でお試しください data = pd.read_csv(path, skiprows=2)


30

CSVファイルには可変数の列がありread_csv、最初の数行から列数を推定する場合があります。この場合、それを解決する2つの方法:

1)CSVファイルを変更して、最大列数のダミーの最初の行を含めます(およびを指定header=[0]

2)またはnames = list(range(0,N))、Nが列の最大数である場合に使用します。


24

ほとんどのcsv CSVはを使用しsep='/t'て作成されるため、これは区切り文字の問題です。セパレーターをread_csv使用してタブ文字(\t)を使用してみてください/t。したがって、次のコード行を使用して開こうとします。

data=pd.read_csv("File_path", sep='\t')

5
@MichaelQueue:これは不正解です。CSVは通常コンマで区切られますが、他の文字でも区切られる場合があります。CSV仕様を参照してください。コンマ、タブ( '\ t')、セミコロン、および場合によっては追加のスペースを使用できます。:)
DJGrandpaJ 2016

私の場合、セパレータの問題でした。read_csvのデフォルトは明らかにカンマであり、カンマを含むテキストフィールドがあります(データはとにかく別のセパレータで保存されていました)
user108569

値にコンマが使用されているが、tabが区切り文字であり、sepが使用されていない場合(または上記で提案されているように、値で発生すると想定される区切り文字はすべて)、このエラーが発生します。区切り文字が値のいずれにも含まれていないことを確認してください。そうしないと、一部の行に正しくない数の列が表示されます
デーモン

CSVの作成中にExcel 2016を使用しており、sep = ';'を使用しています。私のために働く
アブドラは

18

私もこの問題を抱えていましたが、おそらく別の理由でした。私のCSVには、パンダが読み取ろうとした列を追加する末尾のカンマがいくつかありました。次のように動作しますが、それは単に悪い行を無視します:

data = pd.read_csv('file1.csv', error_bad_lines=False)

行を保持したい場合、エラーを処理するための醜い種類のハックは次のようなことをすることです:

line     = []
expected = []
saw      = []     
cont     = True 

while cont == True:     
    try:
        data = pd.read_csv('file1.csv',skiprows=line)
        cont = False
    except Exception as e:    
        errortype = e.message.split('.')[0].strip()                                
        if errortype == 'Error tokenizing data':                        
           cerror      = e.message.split(':')[1].strip().replace(',','')
           nums        = [n for n in cerror.split(' ') if str.isdigit(n)]
           expected.append(int(nums[0]))
           saw.append(int(nums[2]))
           line.append(int(nums[1])-1)
         else:
           cerror      = 'Unknown'
           print 'Unknown Error - 222'

if line != []:
    # Handle the errors however you want

上記のコードの変数 'line'によって不良行が指定されるため、DataFrameに行を再挿入するスクリプトの作成に進みました。これは、csvリーダーを使用するだけで回避できます。うまくいけば、パンダの開発者が将来この状況に対処しやすくなることを願っています。


14

列名を渡さずにCSVを読み取ろうとすると、この問題が発生しました。

df = pd.read_csv(filename, header=None)

事前にリストで列名を指定してに渡したnamesところ、すぐに解決しました。列名を設定していない場合は、データ内の列の最大数と同じ数のプレースホルダー名を作成できます。

col_names = ["col1", "col2", "col3", ...]
df = pd.read_csv(filename, names=col_names)

1
error_bad_line = Falseを使用する場合と比較して、行は削除されないため、この回答はより適切です。さらに、このソリューションからデータフレームを作成すると、どの行が問題であったかを簡単に特定できます。
zipline86

@ zipline86に同意します。この答えは安全でインテリジェントです。
モニカヘドネック

11

私はこの問題を数回経験しました。ほとんどの場合、その理由は、開こうとしたファイルが、もともと適切に保存されたCSVではなかったためです。「適切に」とは、各行のセパレータまたは列の数が同じであることを意味します。

通常は、ExcelでCSVを開いて不適切に保存したことが原因です。ファイル拡張子はまだ.csvでしたが、純粋なCSV形式が変更されていました。

pandas to_csvで保存されたファイルは適切にフォーマットされ、問題は発生しません。ただし、別のプログラムで開くと、構造が変わる場合があります。

お役に立てば幸いです。


8

私は同じ問題に出くわしました。pd.read_table()同じソースファイルで使用するとうまくいくようです。この理由を追跡することはできませんでしたが、これは私の場合に役立つ回避策でした。おそらく、より知識のある誰かが、なぜそれが機能したのかについてより多くの光を当てることができます。

編集:実際のデータと同じ形式ではないテキストがファイルに含まれていると、このエラーが這うことがわかりました。これは通常、ヘッダーまたはフッター情報(1行を超えるため、skip_headerは機能しません)であり、実際のデータと同じ数のコンマで区切られません(read_csvを使用する場合)。read_tableを使用すると、区切り文字としてタブが使用されます。これにより、ユーザーの現在のエラーを回避でき、他のエラーが発生する可能性があります。

私は通常、余分なデータをファイルに読み込んでread_csv()メソッドを使用することでこれを回避します。

正確な解決策は実際のファイルによって異なる場合がありますが、このアプローチはいくつかの場合にうまくいきました


6

以下は私のために働きました(私は特にこの問題をGoogle Colaboratory Notebookで抱えていたため、この回答を投稿しました):

df = pd.read_csv("/path/foo.csv", delimiter=';', skiprows=0, low_memory=False)

1
|.csvの区切り文字として設定しない場合、問題を実験しました。行をスキップするのではなく、このアプローチを最初に試してみるか、悪い行を読みます。
ivanleoncz

私も同じ問題を抱えていました。「\ t」がデフォルトで区切り文字として検出されると思いました。区切り文字を明示的に "\ t"に設定すると機能しました。
Rahul Jha

5

スペース、カンマ、引用符を含むタブ区切りのテーブルを読み込もうとしたときに、同様の問題が発生しました。

1115794 4218    "k__Bacteria", "p__Firmicutes", "c__Bacilli", "o__Bacillales", "f__Bacillaceae", ""
1144102 3180    "k__Bacteria", "p__Firmicutes", "c__Bacilli", "o__Bacillales", "f__Bacillaceae", "g__Bacillus", ""
368444  2328    "k__Bacteria", "p__Bacteroidetes", "c__Bacteroidia", "o__Bacteroidales", "f__Bacteroidaceae", "g__Bacteroides", ""



import pandas as pd
# Same error for read_table
counts = pd.read_csv(path_counts, sep='\t', index_col=2, header=None, engine = 'c')

pandas.io.common.CParserError: Error tokenizing data. C error: out of memory

これは、C構文解析エンジン(デフォルト)と関係があることを示しています。多分Pythonのものに変更すると何でも変更されます

counts = pd.read_table(path_counts, sep='\t', index_col=2, header=None, engine='python')

Segmentation fault (core dumped)

これは別のエラーです。
先に進み、テーブルからスペースを削除しようとすると、python-engineのエラーが再び変化します。

1115794 4218    "k__Bacteria","p__Firmicutes","c__Bacilli","o__Bacillales","f__Bacillaceae",""
1144102 3180    "k__Bacteria","p__Firmicutes","c__Bacilli","o__Bacillales","f__Bacillaceae","g__Bacillus",""
368444  2328    "k__Bacteria","p__Bacteroidetes","c__Bacteroidia","o__Bacteroidales","f__Bacteroidaceae","g__Bacteroides",""


_csv.Error: '   ' expected after '"'

そして、パンダが行の解析に問題を抱えていたことは明らかです。Pythonエンジンでテーブルを解析するには、すべてのスペースと引用符をテーブルから事前に削除する必要がありました。その間、C-engineは行にコンマがあってもクラッシュし続けました。

テーブルが小さいため、置換を使用して新しいファイルを作成しないようにするために、これを行いました。

from io import StringIO
with open(path_counts) as f:
    input = StringIO(f.read().replace('", ""', '').replace('"', '').replace(', ', ',').replace('\0',''))
    counts = pd.read_table(input, sep='\t', index_col=2, header=None, engine='python')

tl; dr
解析エンジンを変更し、データ内の区切り文字のない引用符/カンマ/スペースを避けてください。


5

私が使用したデータセットには、多くの引用符( ")が余分なフォーマットを使用していました。このパラメータを含めることでエラーを修正できましたread_csv()

quoting=3 # 3 correlates to csv.QUOTE_NONE for pandas

2
まったく同じものに出会った。私に関する限り、これは正解です。受け入れられたものはエラーを隠すだけです。
lhk

私も正解です。+1
タハジルジー



3

同様の解析エラーの処理に役立つことがわかった別の方法では、CSVモジュールを使用してデータをpandas dfに再ルーティングします。例えば:

import csv
import pandas as pd
path = 'C:/FileLocation/'
file = 'filename.csv'
f = open(path+file,'rt')
reader = csv.reader(f)

#once contents are available, I then put them in a list
csv_list = []
for l in reader:
    csv_list.append(l)
f.close()
#now pandas has no problem getting into a df
df = pd.DataFrame(csv_list)

CSVモジュールは、コンマで区切られた不適切な形式のファイルに対してもう少し堅牢であるため、このような問題に対処するためにこのルートで成功しました。


3

次の一連のコマンドは機能します(データの最初の行が失われます-ヘッダーなし=なし-少なくとも読み込まれます)。

df = pd.read_csv(filename, usecols=range(0, 42)) df.columns = ['YR', 'MO', 'DAY', 'HR', 'MIN', 'SEC', 'HUND', 'ERROR', 'RECTYPE', 'LANE', 'SPEED', 'CLASS', 'LENGTH', 'GVW', 'ESAL', 'W1', 'S1', 'W2', 'S2', 'W3', 'S3', 'W4', 'S4', 'W5', 'S5', 'W6', 'S6', 'W7', 'S7', 'W8', 'S8', 'W9', 'S9', 'W10', 'S10', 'W11', 'S11', 'W12', 'S12', 'W13', 'S13', 'W14']

以下は機能しません:

df = pd.read_csv(filename, names=['YR', 'MO', 'DAY', 'HR', 'MIN', 'SEC', 'HUND', 'ERROR', 'RECTYPE', 'LANE', 'SPEED', 'CLASS', 'LENGTH', 'GVW', 'ESAL', 'W1', 'S1', 'W2', 'S2', 'W3', 'S3', 'W4', 'S4', 'W5', 'S5', 'W6', 'S6', 'W7', 'S7', 'W8', 'S8', 'W9', 'S9', 'W10', 'S10', 'W11', 'S11', 'W12', 'S12', 'W13', 'S13', 'W14'], usecols=range(0, 42))

CParserError:データのトークン化エラー。Cエラー:1605634行目に53個のフィールドが必要です、54個が見つかりました次は機能しません:

df = pd.read_csv(filename, header=None)

CParserError:データのトークン化エラー。Cエラー:1605634行で53フィールドが必要ですが、54を見ました

したがって、あなたの問題ではあなたが渡す必要があります usecols=range(0, 2)


3

Linux OS上のPython 3で同様の問題を抱えている人のために。

pandas.errors.ParserError: Error tokenizing data. C error: Calling
read(nbytes) on source failed. Try engine='python'.

試してください:

df.read_csv('file.csv', encoding='utf8', engine='python')

2

時々問題はpythonの使い方ではなく、生データにあります。
このエラーメッセージが表示された

Error tokenizing data. C error: Expected 18 fields in line 72, saw 19.

列の説明にコンマが含まれていることがわかりました。つまり、CSVファイルをクリーンアップするか、別のセパレータを使用する必要があります。



1

既存の行番号のデータセットがあり、index_colを使用しました:

pd.read_csv('train.csv', index_col=0)

1

これは私がやったことです。

sep='::' 私の問題を解決しました:

data=pd.read_csv('C:\\Users\\HP\\Downloads\\NPL ASSINGMENT 2 imdb_labelled\\imdb_labelled.txt',engine='python',header=None,sep='::')

1

これと同様のケースと設定がありました

train = pd.read_csv('input.csv' , encoding='latin1',engine='python') 

働いた


1

read_csv:ParserError:エラートークン化データで同じ問題が発生します。古いcsvファイルを新しいcsvファイルに保存しました。問題は解決された!


1

私にとっての問題は、新しい列がCSVの日中に追加されたことでした。私が使用した場合将来のすべての行が破棄されるため、承認された回答ソリューションは機能しませんerror_bad_lines=False

この場合の解決策は、でusecolsパラメータを使用することでしpd.read_csv()。このようにして、CSVに読み込む必要のある列のみを指定でき、ヘッダー列が存在する限り(そして列名が変更されない限り)、Pythonコードは今後のCSVの変更に対応できます。

usecols : list-like or callable, optional 

Return a subset of the columns. If list-like, all elements must either
be positional (i.e. integer indices into the document columns) or
strings that correspond to column names provided either by the user in
names or inferred from the document header row(s). For example, a
valid list-like usecols parameter would be [0, 1, 2] or ['foo', 'bar',
'baz']. Element order is ignored, so usecols=[0, 1] is the same as [1,
0]. To instantiate a DataFrame from data with element order preserved
use pd.read_csv(data, usecols=['foo', 'bar'])[['foo', 'bar']] for
columns in ['foo', 'bar'] order or pd.read_csv(data, usecols=['foo',
'bar'])[['bar', 'foo']] for ['bar', 'foo'] order.

my_columns = ['foo', 'bar', 'bob']
df = pd.read_csv(file_path, usecols=my_columns)

これのもう1つの利点は、18〜20列のCSVの3〜4列のみを使用している場合に、メモリにロードするデータをはるかに少なくできることです。


1

簡単な解決:csvファイルをExcelで開き、csv形式の別の名前のファイルで保存します。もう一度スパイダーをインポートしてみてください。問題は解決されます!


1

引用符が外れているこのエラーが発生しました。カンマ区切りのファイルをエクスポートするときに、テキストアイテムを引用符で囲むマッピングソフトウェアを使用しています。引用符を使用するテキスト(たとえば、「=フィート」と「=インチ」)は、区切り文字の衝突を引き起こす場合に問題となる可能性があります。

UWI_key,Latitude,Longitude,Remark US42051316890000,30.4386484,-96.4330734,"poor 5""

5"短縮形として使用すると5 inch、作業中にレンチを投げることになります。Excelは単に余分な引用符を取り除きますが、Pandasはerror_bad_lines=False上記の議論なしで失敗します。


1

私が知る限り、ファイルを確認した後、問題は、ロードしようとしているcsvファイルに複数のテーブルがあることです。空の行、またはテーブルのタイトルを含む行があります。このStackoverflowの回答をご覧ください。プログラムでそれを達成する方法を示しています。

これを行う別の動的なアプローチは、csvモジュールを使用することです。一度にすべての行を読み取り性チェック/正規表現を実行して、行が(タイトル/ヘッダー/値/空白)かどうかを推測することです。このアプローチには、必要に応じてデータをPythonオブジェクトに分割/追加/収集できるというもう1つの利点があります。

すべての最も簡単な方法はpd.read_clipboard()、Excelか何かでcsvを開くことができる場合に備えて、テーブルを手動で選択してクリップボードにコピーした後でパンダ関数を使用することです。

無関係

さらに、あなたの問題と無関係ですが、誰もこれについて言及していなかったためです。UCI seeds_dataset.txtからなどの一部のデータセットをロードするときにも同じ問題が発生しました。私の場合、一部のセパレータに実際のタブよりも多くの空白があるため、エラーが発生していました\t。たとえば、次の3行目を参照してください

14.38   14.21   0.8951  5.386   3.312   2.462   4.956   1
14.69   14.49   0.8799  5.563   3.259   3.586   5.219   1
14.11   14.1    0.8911  5.42    3.302   2.7     5       1

したがって、の\t+代わりにセパレータパターンで使用し\tます。

data = pd.read_csv(path, sep='\t+`, header=None)

1

私の場合、csvファイルの最初と最後の2行の形式がファイルの中央のコンテンツと異なるためです。

したがって、csvファイルを文字列として開き、文字列の内容を解析してread_csvから、データフレームを取得するために使用します。

import io
import pandas as pd

file = open(f'{file_path}/{file_name}', 'r')
content = file.read()

# change new line character from '\r\n' to '\n'
lines = content.replace('\r', '').split('\n')

# Remove the first and last 2 lines of the file
# StringIO can be considered as a file stored in memory
df = pd.read_csv(StringIO("\n".join(lines[2:-2])), header=None)

1

私の場合、セパレータはデフォルトの "、"ではなく、タブでした。

pd.read_csv(file_name.csv, sep='\\t',lineterminator='\\r', engine='python', header='infer')

注:「\ t」は、一部のソースで推奨されているように機能しませんでした。「\\ t」が必要でした。


0

同様のエラーがあり、csvファイルにエスケープされた引用符がいくつかあり、escapecharパラメータを適切に設定する必要があるという問題がありました。

弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.