Python Pandas Ошибка токенизации данных

343

Я пытаюсь использовать панд для манипулирования файлом .csv, но я получаю эту ошибку:

pandas.parser.CParserError: Ошибка токенизации данных. Ошибка С: ожидается 2 поля в строке 3, пила 12

Я пытался читать документы панд, но ничего не нашел.

Мой код прост:

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

Как я могу решить это? Должен ли я использовать csvмодуль или другой язык?

Файл от Morningstar

abuteau
источник
10
Если эта ошибка возникает при чтении файла, записанного с помощью pandas.to_csv(), МОЖЕТ быть, потому что в именах столбцов есть '\ r', и в этом случае to_csv () фактически записывает последующие имена столбцов в первый столбец фрейма данных, вызывая разница между количеством столбцов в первых X строках. Эта разница является одной из причин ошибки C.
user0
9
Иногда помогает явное указание параметра "sep". Кажется, проблема с парсером.
Гильгамаш
2
Эта ошибка также может возникать, когда вы используете запятую в качестве разделителя и у вас больше запятых, чем ожидалось (больше полей в строке ошибки, чем определено в заголовке). Таким образом, вам нужно либо удалить дополнительное поле, либо удалить лишнюю запятую, если она там есть по ошибке. Вы можете исправить это вручную, и тогда вам не нужно пропускать строки ошибок.
Цветы_ико
2
Комментарий от Гильгамаша помог мне. Откройте CSV-файл в текстовом редакторе (например, Windows Editor или Notepad ++), чтобы увидеть, какой символ используется для разделения. Если это точка с запятой, например, попробуйте pd.read_csv("<path>", sep=";"). Не используйте Excel для проверки, так как он иногда помещает данные в столбцы по умолчанию и поэтому удаляет разделитель.
Джулиан
Что касается комментария @gilgamash - это направило меня в правильном направлении, однако в моем случае это было решено явным отсутствием параметра "sep".
TheLoneDeranger

Ответы:

515

Вы также можете попробовать;

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

Обратите внимание, что это приведет к пропуску ошибочных строк.

Richie
источник
152
Обратите внимание, что использование error_bad_lines = False приведет к пропуску ошибочных строк.
биобирмен
10
Наткнулся на этот ответ, есть ли способ заполнить пропущенные столбцы в строках, которые выводят что-то вроде expected 8 fields, saw 9?
Петра Барус
26
Лучшее решение - исследовать файл-нарушитель и исправить неправильные строки, чтобы они могли быть прочитаны read_csv. @PetraBarus, почему бы просто не добавить столбцы в файлы CSV, в которых они отсутствуют (с нулевыми значениями при необходимости)?
dbliss
4
Да, я только что сделал это. Это гораздо проще, добавив столбцы. Открытие CSV в электронной таблице делает это.
Петра Барус
5
Также работает передача names=["col1", "col2", ...]максимального числа ожидаемых столбцов, и именно так я решил эту проблему, когда натолкнулся на нее. Смотрите: stackoverflow.com/questions/18039057/…
Стивен Рук
100

Это может быть проблема с

  • разделители в ваших данных
  • первый ряд, как заметил @TomAugspurger

Чтобы решить эту проблему, попробуйте указать аргументы sepand и / или headerпри вызове read_csv. Например,

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

В приведенном выше коде sepопределяет ваш разделитель и header=Noneсообщает пандам, что в ваших исходных данных нет строки для заголовков / заголовков столбцов. Таким образом, документация гласит : «Если файл не содержит строки заголовка, вы должны явно передать header = None». В этом случае pandas автоматически создает индексы целых чисел для каждого поля {0,1,2, ...}.

Согласно документам, разделитель не должен быть проблемой. В документах говорится, что «если sep равен None [не указан], он попытается автоматически определить это». Однако мне не повезло с этим, в том числе с очевидными разделителями.

grisaitis
источник
Да, иногда причиной этой проблемы может быть разделитель. Я столкнулся с той же проблемой, когда разделитель был точкой с запятой (;)
Анураг Шарма
43

Парсер запутывается в заголовке файла. Он читает первую строку и выводит количество столбцов из этой строки. Но первые две строки не представляют фактические данные в файле.

Попробуй это с data = pd.read_csv(path, skiprows=2)

TomAugspurger
источник
30

Ваш CSV-файл может иметь переменное количество столбцов и read_csvвыводить количество столбцов из первых нескольких строк. Два способа решить это в этом случае:

1) Измените файл CSV, чтобы иметь фиктивную первую строку с максимальным количеством столбцов (и укажите header=[0])

2) Или используйте names = list(range(0,N))где N максимальное количество столбцов.

computerist
источник
25

Это определенно проблема разделителя, так как большинство CSV-файлов CSV создаются с использованием, sep='/t'поэтому попробуйте read_csvиспользовать символ табуляции (\t)с помощью разделителя /t. Итак, попробуйте открыть, используя следующую строку кода.

data=pd.read_csv("File_path", sep='\t')
Пиюш С. Ванаре
источник
5
@MichaelQueue: это неверно. CSV, хотя обычно разделяются запятой, могут быть разделены и другими символами. Смотрите спецификации CSV . Это может быть запятая, табуляция ('\ t'), точка с запятой и, возможно, дополнительные пробелы. :)
DJGrandpaJ
в моем случае это была проблема с разделителем. read_csv, по-видимому, по умолчанию использует запятые, и у меня есть текстовые поля, которые включают запятые (и в любом случае данные были сохранены с другим разделителем)
user108569
Если в значениях используются запятые, а tab - это разделитель, а sep не используется (или, как предложено выше, разделители, как предполагается, встречаются в значениях), то эта ошибка возникнет. Убедитесь, что разделитель не встречается ни в одном из значений, иначе в некоторых строках будет указано неправильное количество столбцов
demongolem
Я использую Excel 2016 при создании CSV и 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

Я приступил к написанию сценария для повторной вставки строк в DataFrame, поскольку плохие строки будут заданы переменной 'line' в приведенном выше коде. Этого можно избежать, просто используя csv reader. Надеемся, что разработчики панд помогут в будущем справиться с этой ситуацией.

Роберт Гейгер
источник
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 для начала. И под «правильно» я подразумеваю, что каждая строка имеет одинаковое количество разделителей или столбцов.

Обычно это происходит потому, что я открыл CSV в Excel, а затем неправильно его сохранил. Несмотря на то, что расширение файла было все еще .csv, чистый формат CSV был изменен.

Любой файл, сохраненный с помощью pandas to_csv, будет правильно отформатирован и не должен иметь такой проблемы. Но если вы откроете его с помощью другой программы, это может изменить структуру.

Надеюсь, это поможет.

elPastor
источник
8

Я столкнулся с той же проблемой. Использование pd.read_table()одного и того же исходного файла, похоже, работает. Я не мог проследить причину этого, но это был полезный обходной путь для моего случая. Возможно, кто-то более знающий может пролить больше света на то, почему это работает.

Изменить: я обнаружил, что эта ошибка появляется, когда у вас есть текст в вашем файле, который не имеет тот же формат, что и фактические данные. Обычно это информация верхнего или нижнего колонтитула (больше, чем одна строка, поэтому skip_header не работает), которая не будет разделена тем же количеством запятых, что и ваши фактические данные (при использовании read_csv). При использовании read_table в качестве разделителя используется вкладка, которая может обойти текущую ошибку пользователя, но представить другие.

Я обычно обхожу это путем чтения дополнительных данных в файл, а затем использую метод read_csv ().

Точное решение может отличаться в зависимости от вашего фактического файла, но этот подход работал для меня в нескольких случаях

Legend_Ari
источник
6

Следующее работает для меня (я опубликовал этот ответ, потому что у меня была эта проблема в записной книжке Google Colab Laboratory):

df = pd.read_csv("/path/foo.csv", delimiter=';', skiprows=0, low_memory=False)
кортик
источник
1
Я экспериментировал с проблемами, когда не устанавливал |в качестве разделителя для моего .csv. Я предпочитаю сначала попробовать этот подход, а не пропускать строки или плохие строки.
ivanleoncz
У меня также была та же проблема, я предполагал, что «\ t» будет определен как разделитель по умолчанию. Это сработало, когда я явно установил разделитель на «\ t».
Рахул Джа
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

Это говорит о том, что это как-то связано с механизмом синтаксического анализа языка Си (по умолчанию). Может быть, переход на питон изменит что-нибудь

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 Engine мне нужно было заранее удалить все пробелы и кавычки из таблицы. Тем временем C-двигатель продолжал падать даже с запятыми в строках.

Чтобы избежать создания нового файла с заменами, я сделал это, так как мои таблицы маленькие:

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
Измените механизм синтаксического анализа, постарайтесь избегать любых не разделяющих кавычек / запятых / пробелов в ваших данных.

lotrus28
источник
5

В наборе данных, который я использовал, было много кавычек ("), использующих постороннее форматирование. Я смог исправить ошибку, включив этот параметр для read_csv():

quoting=3 # 3 correlates to csv.QUOTE_NONE for pandas
user3426943
источник
2
наткнулся на то же самое. Насколько я понимаю, это правильный ответ. Принятый просто скрывает ошибку.
ЛХК
Правильный ответ для меня тоже. +1
Таха Джирджис
4

Использовать разделитель в параметре

pd.read_csv(filename, delimiter=",", encoding='utf-8')

Это будет читать.

Бхавеш Кумар
источник
3

Хотя это и не относится к этому вопросу, эта ошибка также может появляться со сжатыми данными. Явно установив значение для kwarg compressionрешенной моей проблемы.

result = pandas.read_csv(data_source, compression='gzip')
RegularlyScheduledProgramming
источник
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 немного более устойчив к плохо отформатированным файлам, разделенным запятыми, и поэтому успешно справился с этим путем для решения подобных проблем.

bcoz
источник
3

работает следующая последовательность команд (я теряю первую строку данных -no header = None присутствует-, но по крайней мере она загружается):

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: Ожидается 53 поля в строке 1605634, пила 54 Следующее НЕ работает:

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

CParserError: Ошибка токенизации данных. Ошибка C: ожидается 53 поля в строке 1605634, видел 54

Следовательно, в вашей проблеме вы должны пройти usecols=range(0, 2)

kepy97
источник
3

Для тех, у кого похожая проблема с Python 3 на ОС Linux.

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')
Zstack
источник
2

Иногда проблема не в том, как использовать python, а в необработанных данных.
Я получил это сообщение об ошибке

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

Оказалось, что в описании колонки были иногда запятые. Это означает, что файл CSV необходимо очистить или использовать другой разделитель.

Кимс Сиферс
источник
2

использование pandas.read_csv('CSVFILENAME',header=None,sep=', ')

при попытке прочитать данные csv по ссылке

http://archive.ics.uci.edu/ml/machine-learning-databases/adult/adult.data

Я скопировал данные с сайта в мой csvfile. У него были лишние пробелы, поэтому использовали sep = ',', и это сработало :)

Абхишек
источник
1

У меня был набор данных с существующими номерами строк, я использовал index_col:

pd.read_csv('train.csv', index_col=0)
gogasca
источник
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') 

работал

Adewole Adesola
источник
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)

Еще одним преимуществом этого является то, что я могу загружать намного меньше данных в память, если я использую только 3-4 столбца CSV, который имеет 18-20 столбцов.

Скотт Скилз
источник
1

Простое разрешение : откройте файл CSV в Excel и сохраните его с другим именем файла формата CSV. Снова попробуйте импортировать его spyder, Ваша проблема будет решена!

Naseer
источник
1

Я столкнулся с этой ошибкой с кавычками. Я использую картографическое программное обеспечение, которое ставит кавычки вокруг текстовых элементов при экспорте файлов с разделителями-запятыми. Текст, который использует кавычки (например, '= футы и "= дюймы), может вызвать проблемы, когда затем вызывает столкновения с разделителями. Рассмотрим этот пример, который отмечает, что 5-дюймовая печать каротажа скважины плохая:

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 , чтение каждой строки за раз и выполнение проверок работоспособности / регулярных выражений, чтобы определить, является ли строка (title / header / values ​​/ blank). У вас есть еще одно преимущество в этом подходе: вы можете разделять / добавлять / собирать ваши данные в объектах Python по желанию.

Проще всего было бы использовать функцию pandas pd.read_clipboard()после ручного выбора и копирования таблицы в буфер обмена, если вы можете открыть CSV в Excel или что-то еще.

Не имеет значения :

Кроме того, не имеет отношения к вашей проблеме, но потому что никто не упомянул об этом : у меня была такая же проблема при загрузке некоторых наборов данных, таких как seeds_dataset.txtиз UCI. В моем случае ошибка произошла, потому что некоторые разделители имели больше пробелов, чем истинная вкладка \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 отличается от среднего содержимого файла.

Поэтому я открываю файл 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

В моем случае разделитель был не по умолчанию ",", а Tab.

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

Примечание: «\ t» не работает, как предлагают некоторые источники. Требуется \\ t.

Mihai.Mehe
источник
0

У меня была похожая ошибка, и проблема заключалась в том, что у меня были некоторые экранированные кавычки в моем CSV-файле, и мне нужно было правильно установить параметр escapechar.

jvvw
источник