Помилка Pandas Python Помилка токенізації даних


343

Я намагаюся використовувати панди для маніпулювання файлом .csv, але я отримую цю помилку:

pandas.parser.CParserError: помилка в маркуванні даних. C помилка: очікується 2 поля у рядку 3, побачив 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.
користувач0

9
Десь просто явно надання параметра "sep" допомагає. Здається, це питання парсера.
gilgamash

2
Ця помилка може виникнути і тоді, коли ви використовуєте косу як роздільник, і у вас більше косів, ніж очікувалося (більше полів у рядку помилок, а потім визначено у заголовку). Тож вам потрібно або видалити додаткове поле, або видалити зайву кому, якщо воно є помилково. Ви можете це виправити вручну, і тоді вам не потрібно буде пропускати рядки помилок.
tsveti_iko

2
Коментар від gilgamash мені допоміг. Відкрийте файл csv в текстовому редакторі (наприклад, редактор Windows або блокнот ++), щоб побачити, який символ використовується для розділення. Якщо це крапка з комою, наприклад, спробуйте pd.read_csv("<path>", sep=";"). Не використовуйте Excel для перевірки, оскільки він іноді ставить дані у стовпці за замовчуванням і тому видаляє роздільник.
Джуліан

Щодо коментаря @gilgamash - це направило мене в правильному напрямку, однак у моєму випадку це було вирішено, явно не задавши параметр "sep".
TheLoneDeranger

Відповіді:


515

ви також можете спробувати;

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

Зверніть увагу, що це призведе до пропускання порушень.


152
Зауважте, що використання error_bad_lines = False призведе до пропуску рядків порушень.
biobirdman

10
Наткнувшись на цю відповідь, чи є спосіб заповнити пропущені стовпці на рядках, які видають щось на кшталт expected 8 fields, saw 9?
Петра Барус

26
Кращим рішенням є дослідження файлу, що порушує право, та виправлення поганих рядків, щоб їх можна було прочитати read_csv. @PetraBarus, чому б не просто додати стовпці до файлів CSV, у яких вони відсутні (з нульовими значеннями, якщо потрібно)?
dbliss

4
Так, я просто це зробив. Набагато простіше, додаючи стовпці. Відкриття CSV в електронній таблиці робить це.
Петра Барус

5
Проходження names=["col1", "col2", ...]для максимальної кількості очікуваних стовпців також працює, і ось як я вирішив цю проблему, коли натрапив на неї. Див: stackoverflow.com/questions/18039057 / ...
Стівен Rõuk

100

Це може бути проблема з

  • роздільники ваших даних
  • перший рядок, як зазначав @TomAugspurger

Щоб вирішити це, спробуйте вказати sepта / або headerаргументи під час виклику read_csv. Наприклад,

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

У наведеному вище коді sepвизначається ваш роздільник та header=Noneповідомляється пандам, що у вихідних даних немає рядка для заголовків / заголовків стовпців. Таким чином, каже документи : "Якщо файл не містить рядка заголовка, вам слід явно передавати заголовок = None". У цьому випадку панди автоматично створюють індекси з цілою кількістю для кожного поля {0,1,2, ...}.

Згідно з документами, розмежувач не повинен бути проблемою. Документи кажуть, що "якщо sep є None [не вказано], спробує це автоматично визначити". Проте мені не пощастило з цим, включаючи випадки з очевидними роздільниками.


Так, іноді розмежувач може бути причиною цього питання. Я зіткнувся з тим же питанням, де роздільником було крапку з комою (;)
Анураг Шарма

43

Аналізатор заплутається в заголовку файлу. Він читає перший рядок і визначає кількість стовпців з цього рядка. Але перші два рядки не є реальними реальними даними у файлі.

Спробуйте data = pd.read_csv(path, skiprows=2)


30

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

1) Змініть файл CSV, щоб мати макетний перший рядок із максимальною кількістю стовпців (та вкажіть header=[0])

2) Або використовувати names = list(range(0,N))там, де N - максимальна кількість стовпців.


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

Якщо в значеннях використовуються коми, але вкладка - це роздільник, а сеп не використовується (або, як було запропоновано вище розділювачів, усе, що передбачається, у значеннях), ця помилка виникне. Переконайтеся, що роздільник не зустрічається в жодному зі значень, а в деяких рядках з'явиться неправильна кількість стовпців
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, оскільки погані рядки будуть задані змінною 'рядок' у наведеному вище коді. Цього можна уникнути, просто скориставшись читачем 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 для початку. І, маючи на увазі "правильно", я маю на увазі, що кожен рядок мав однакову кількість роздільників або стовпців.

Зазвичай це сталося тому, що я відкрив CSV в Excel, а потім неправильно зберег його. Незважаючи на те, що розширення файлу все ще було .csv, чистий формат CSV був змінений.

Будь-який файл, збережений за допомогою панд to_csv, буде належним чином відформатований і не повинен мати цю проблему. Але якщо відкрити його за допомогою іншої програми, це може змінити структуру.

Сподіваюся, що це допомагає.


8

Я зіткнувся з тим же питанням. Використання pd.read_table()одного і того ж вихідного файлу, здавалося, працює. Я не міг простежити причину цього, але це було корисним рішенням для моєї справи. Можливо, хтось більш обізнаний може пролити більше світла на те, чому це працювало.

Редагувати: Я виявив, що ця помилка повстає, коли у вашому файлі є текст, який не має такого формату, як фактичні дані. Зазвичай це інформація заголовка або колонтитула (більше одного рядка, тому skip_header не працює), яка не буде відокремлена тим самим числом коми, що і ваші фактичні дані (при використанні read_csv). Використання read_table використовує вкладку як роздільник, який може обійти поточну помилку користувачів, але ввести інші.

Зазвичай я обходжу це, читаючи зайві дані у файлі, а потім використовую метод read_csv ().

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


6

Наступне працювало для мене (я опублікував цю відповідь, тому що конкретно у мене була ця проблема в зошиті Google Colaboratory):

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

Це говорить про те, що це має відношення до двигуна розбору C (який є типовим). Можливо, перехід на пітон змінить щось

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-двигун продовжував тріскатися навіть комами в рядках.

Щоб уникнути створення нового файлу із замінами, я це зробив, оскільки мої таблиці невеликі:

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
Taha Jirjees

4

Використовуйте роздільник у параметрі

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

Він буде читати.


3

Хоча це питання не стосується, ця помилка може з’являтися і при стиснених даних. Явне встановлення значення для kwarg compressionвирішення моєї проблеми.

result = pandas.read_csv(data_source, compression='gzip')

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

працює наступна послідовність команд (я втрачаю перший рядок даних -no header = Жодного немає, але принаймні завантажується):

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)


3

Для тих, хто має подібні проблеми з Python 3 в Linux 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')

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)

Ще однією перевагою цього є те, що я можу завантажувати набагато менше даних у пам’ять, якщо використовую лише 3-4 стовпці CSV, які мають 18-20 стовпців.


1

Просте дозвіл : Відкрийте файл CSV у програмі excel та збережіть його з іншим файлом імен формату CSV. Знову спробуйте імпортувати шпигун, Ваша проблема буде вирішена!


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, який ви намагаєтеся завантажити, є кілька таблиць. Є порожні рядки або рядки, що містять назви таблиць. Спробуйте ознайомитись із цією відповіддю Стакковержа . Це показує, як цього досягти програмно.

Іншим динамічним підходом до цього є використання модуля csv , зчитування кожного рядка за один раз та здійснення перевірок правильності / регулярних виразів, щоб зробити висновок, якщо рядок є (заголовок / заголовок / значення / порожній). У вас є ще одна перевага при такому підході: ви можете розділити / додавати / збирати свої дані в об’єкти python за бажанням.

Найпростіше було б скористатися функцією pandas pd.read_clipboard()після вибору та копіювання таблиці в буфер обміну вручну, на випадок, якщо ви можете відкрити csv в excel або щось інше.

Неважливо :

Крім того, це не стосується вашої проблеми, але через те, що ніхто не згадував про це : у мене була ця сама проблема під час завантаження деяких наборів даних, таких як seeds_dataset.txtUCI. У моєму випадку помилка сталася через те, що деякі роздільники мали більше пробілів, ніж справжня вкладка \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".


0

У мене була подібна помилка. Проблема полягала в тому, що у мене у файлі csv були якісь уникні лапки, і мені потрібно було відповідним чином встановити параметр escapechar.

Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.