_csv.Error: поле більше, ніж межа поля (131072)


232

У мене сценарій читання у файлі CSV з дуже величезними полями:

# example from http://docs.python.org/3.3/library/csv.html?highlight=csv%20dictreader#examples
import csv
with open('some.csv', newline='') as f:
    reader = csv.reader(f)
    for row in reader:
        print(row)

Однак це призводить до наступної помилки для деяких файлів csv:

_csv.Error: field larger than field limit (131072)

Як я можу аналізувати файли CSV з величезними полями? Пропуск рядків з величезними полями не є можливим, оскільки дані потрібно аналізувати в наступних кроках.


10
Ще краще було б подумати, чому існують такі великі поля Чи очікується це у ваших даних? Іноді такі помилки свідчать про іншу проблему. У мене були погані дані, які включали випадковий символ подвійної цитати, і тому мені довелося використовувати параметр QUOTE_NONE, показаний в іншій відповіді тут.
пиломашина

1
Я оновив своє запитання, щоб вказати, що в моєму випадку можуть виникнути величезні поля. У файлі csv немає поганих даних.
користувач1251007

1
@dustmachine Такі речі трапляються тому, що іноді в таблицях баз даних люди зберігають зображення (або інші двійкові файли) у форматі base64.
Wintermute

Відповіді:


315

Файл csv може містити дуже величезні поля, тому збільште field_size_limit:

import sys
import csv

csv.field_size_limit(sys.maxsize)

sys.maxsizeпрацює для Python 2.x та 3.x. sys.maxintпрацював би лише з Python 2.x ( SO: what-is-sys-maxint-in-python-3 )

Оновлення

Як Geoff зазначив, наведений вище код може привести до наступної помилки: OverflowError: Python int too large to convert to C long. Щоб обійти це, ви можете використовувати наступний швидкий і брудний код (який повинен працювати в будь-якій системі з Python 2 і Python 3):

import sys
import csv
maxInt = sys.maxsize

while True:
    # decrease the maxInt value by factor 10 
    # as long as the OverflowError occurs.

    try:
        csv.field_size_limit(maxInt)
        break
    except OverflowError:
        maxInt = int(maxInt/10)

14
У Windows 7 64bit з Python 2.6, maxInt = sys.maxsizeповернення, 9223372036854775807Lяке, відповідно, призводить до TypeError: limit must be an integerвиклику при виклику csv.field_size_limit(maxInt). Цікаво, що використання maxInt = int(sys.maxsize)цього не змінює. Грубим способом є спрощене використання, csv.field_size_limit(2147483647)що, звичайно, спричиняє проблеми на інших платформах. У моєму випадку це було adquat для визначення розбитого значення в CSV, виправлення параметрів експорту в іншій програмі та усунення необхідності csv.field_size_limit().
roskakori

велике спасибі за це, Айв протягом століть намагався розібратися в цьому помилку!
Кевін Ернандес

152

Це може бути тому, що у ваш файл CSV вбудовані одиничні чи подвійні лапки. Якщо ваш файл CSV розміщений на вкладках, спробуйте відкрити його як:

c = csv.reader(f, delimiter='\t', quoting=csv.QUOTE_NONE)

1
Дякую!! Якщо ви використовуєте csvkit (відмінна бібліотека python та командний рядок csv toolkit) і отримуєте оригінальну помилку, оскільки у вашому файлі використовуються незбалансовані одинарні чи подвійні лапки, ви можете вибрати QUOTE_NONE за допомогою параметра -u 3командного рядка, так само--quoting 3
nealmcb

22

Нижче - перевірити межу струму

csv.field_size_limit()

Вихід [20]: 131072

Нижче - збільшення ліміту. Додайте його до коду

csv.field_size_limit(100000000)

Спробуйте перевірити ліміт ще раз

csv.field_size_limit()

Вихід [22]: 100000000

Тепер ви не отримаєте помилку "_csv.Error: поле більше, ніж межа поля (131072)"


15

Розміри полів csv управляються через [Python 3.Docs]: csv. field_size_limit ( [new_limit] ) :

Повертає поточний максимальний розмір поля, дозволений аналізатором. Якщо задано new_limit , це стає новим обмеженням.

За замовчуванням встановлено 128k або 0x20000 ( 131072 ), що повинно вистачити для будь-якого пристойного .csv :

>>> import csv
>>>
>>> limit0 = csv.field_size_limit()
>>> limit0
131072
>>> "0x{0:016X}".format(limit0)
'0x0000000000020000'

Однак, маючи справу з файлом .csv ( з правильним цитуванням та роздільником ), що має (принаймні) на одне поле довше цього розміру, помилка з’являється.
Щоб позбутися помилки, слід збільшити обмеження розміру (щоб уникнути будь-яких турбот, спробується максимально можливе значення).

За лаштунками (перевірте [GitHub]: python / cpython - (master) cpython / Modules / _csv.c на деталі реалізації), змінна, яка містить це значення, є C довгою ( [Wikipedia]: типи даних C ), розмір якої змінюється в залежності від архітектури процесора та ОС ( I L P ). Класична різниця: для 64-бітної ОС ( збірка Python ) розмір довгого типу ( у бітах ) становить:

  • Нікс : 64
  • Виграш : 32

При спробі встановити це нове значення перевіряється на довгі межі, тому в деяких випадках з'являється інший виняток (цей випадок поширений у програмі Win ):

>>> import sys
>>>
>>> sys.platform, sys.maxsize
('win32', 9223372036854775807)
>>>
>>> csv.field_size_limit(sys.maxsize)
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
OverflowError: Python int too large to convert to C long

Щоб не стикатися з цією проблемою, встановіть (максимально можливий) ліміт ( LONG_MAX ) за допомогою штучного інструменту (завдяки [Python 3.Docs]: ctypes - Бібліотека іноземних функцій для Python ). Він повинен працювати на Python 3 та Python 2 , на будь-якому процесорі / ОС .

>>> import ctypes as ct
>>>
>>> csv.field_size_limit(int(ct.c_ulong(-1).value // 2))
131072
>>> limit1 = csv.field_size_limit()
>>> limit1
2147483647
>>> "0x{0:016X}".format(limit1)
'0x000000007FFFFFFF'

64-бітний Python на таких операційних системах, як Nix :

>>> import sys, csv, ctypes as ct
>>>
>>> sys.platform, sys.maxsize
('linux', 9223372036854775807)
>>>
>>> csv.field_size_limit()
131072
>>>
>>> csv.field_size_limit(int(ct.c_ulong(-1).value // 2))
131072
>>> limit1 = csv.field_size_limit()
>>> limit1
9223372036854775807
>>> "0x{0:016X}".format(limit1)
'0x7FFFFFFFFFFFFFFF'

Для 32-бітного Python все є рівномірним: це поведінка, яку зустрічає Win .

Щоб отримати докладнішу інформацію, перегляньте такі ресурси:


2

У мене щойно це траплялося зі звичайним файлом CSV. Деякі люди можуть назвати це недійсним форматованим файлом. Без символів втечі, жодних подвійних лапок та роздільника не було крапки з комою.

Зразок рядка з цього файлу виглядатиме так:

Перша клітина; Друга клітинка з однією подвійною цитатою та провідним простором; клітинка "Частково цитується";

одинарна цитата у другій комірці кинула б парсер зі своїх рейок. Що працювало:

csv.reader(inputfile, delimiter=';', doublequote='False', quotechar='', quoting=csv.QUOTE_NONE)

1

Іноді рядки містять подвійний стовпчик цитат. Коли csv читач спробує прочитати цей рядок, не зрозумілий кінець стовпця і запустити цей рейз. Рішення нижче:

reader = csv.reader(cf, quoting=csv.QUOTE_MINIMAL)

0

Ви можете використовувати read_csvз, pandasщоб пропустити ці рядки.

import pandas as pd

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

Немає поганих рядків ... як написано у запитанні: Файли csv містять величезні поля, і ці дані потрібно проаналізувати.
user1251007

1
Концепція поганих рядків у pandasвключає рядки, які перевищують межу поля csv. Отже, якщо ви хочете пропустити ці рядки та успішно прочитати інші рядки, ви можете скористатися цим рішенням. В іншому випадку, коли вам потрібні величезні поля, збільшення межі поля csv.field_size_limit(100000000)доцільно.
0x01h

-1

Знайдіть файл cqlshrc, зазвичай розміщений у каталозі .cassandra.

У цьому файлі додайте,

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