_csv.Error: pole większe niż limit pola (131072)


232

Mam skrypt do odczytu w pliku csv z bardzo dużymi polami:

# 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)

Jednak powoduje to następujący błąd w niektórych plikach csv:

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

Jak mogę analizować pliki csv z dużymi polami? Pomijanie wierszy z dużymi polami nie jest opcją, ponieważ dane należy analizować w kolejnych krokach.


10
Jeszcze lepiej byłoby rozważyć, dlaczego istnieją tak duże pola. Czy jest to oczekiwane w twoich danych? Czasami takie błędy wskazują na inny problem. Miałem swoje złe dane, które zawierały losowy znak podwójnego cudzysłowu i dlatego musiałem użyć opcji QUOTE_NONE pokazanej w innej odpowiedzi tutaj.
— dustmachine 21.04.16

1
Zaktualizowałem moje pytanie, aby wskazać, że w moim przypadku mogą wystąpić ogromne pola. W pliku csv nie ma złych danych.
— 21.04.2016

1
@dustmachine Takie rzeczy się zdarzają, ponieważ czasami ludzie przechowują obrazy (lub inne pliki binarne) w formacie base64 w tabelach baz danych.
— wintermute

Odpowiedzi:


315

Plik csv może zawierać bardzo duże pola, dlatego zwiększ field_size_limit:

import sys
import csv

csv.field_size_limit(sys.maxsize)

sys.maxsizedziała dla Python 2.xi 3.x. sys.maxintdziała tylko z Python 2.x ( SO: what-is-sys-maxint-in-python-3 )

Aktualizacja

Jak Geoff zauważył, powyższy kod może spowodować następujący błąd: OverflowError: Python int too large to convert to C long. Aby to obejść, możesz użyć następującego szybkiego i brudnego kodu (który powinien działać na każdym systemie z Python 2 i 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
W systemie Windows 7 64bit z Python 2.6 maxInt = sys.maxsizezwraca, 9223372036854775807Lco w konsekwencji powoduje TypeError: limit must be an integerwywołanie podczas csv.field_size_limit(maxInt). Co ciekawe, używanie maxInt = int(sys.maxsize)tego nie zmienia. Prostym obejściem jest uproszczone użycie, csv.field_size_limit(2147483647)które oczywiście powoduje problemy na innych platformach. W moim przypadku było to adekwatne do zidentyfikowania zepsutej wartości w pliku CSV, ustalenia opcji eksportu w drugiej aplikacji i usunięcia potrzeby csv.field_size_limit().
— roskakori

dziękuję bardzo za to, od wieków próbowałem znaleźć ten błąd!
— Kevin Hernandez

152

Może to być spowodowane tym, że plik CSV ma osadzone pojedyncze lub podwójne cudzysłowy. Jeśli plik CSV jest rozdzielany tabulatorami, spróbuj go otworzyć jako:

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

1
Dziękuję Ci!! Jeśli używasz csvkit (doskonała biblioteka Pythona i zestaw narzędzi csv wiersza polecenia) i otrzymujesz oryginalny błąd, ponieważ plik używa niesymetrycznych pojedynczych lub podwójnych cudzysłowów, możesz wybrać QUOTE_NONE za pomocą -u 3opcji wiersza polecenia, alias--quoting 3
— nealmcb 25.01.15

22

Poniżej znajduje się sprawdzenie aktualnego limitu

csv.field_size_limit()

Out [20]: 131072

Poniżej jest zwiększenie limitu. Dodaj to do kodu

csv.field_size_limit(100000000)

Spróbuj ponownie sprawdzić limit

csv.field_size_limit()

Out [22]: 100000000

Teraz nie pojawi się błąd „_csv.Error: pole większe niż limit pola (131072)”


15

Rozmiary pól csv są kontrolowane przez [Python 3.Docs]: csv. field_size_limit ( [new_limit] ) :

Zwraca bieżący maksymalny rozmiar pola dozwolony przez analizator składni. Jeśli podano new_limit , staje się to nowym limitem.

Domyślnie jest ustawiony na 128k lub 0x20000 ( 131072 ), co powinno wystarczyć dla każdego porządnego pliku .csv :

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

Jednak w przypadku pliku .csv ( z poprawnym cytowaniem i separatorem ) mającego (przynajmniej) jedno pole dłuższe niż ten rozmiar, pojawia się błąd.
Aby pozbyć się błędu, należy zwiększyć limit rozmiaru (aby uniknąć obaw, próbowana jest maksymalna możliwa wartość).

Za kulisami (sprawdź [GitHub]: python / cpython - (master) cpython / Modules / _csv.c, aby uzyskać szczegółowe informacje na temat implementacji), zmienna przechowująca tę wartość ma długość C ( [Wikipedia]: typy danych C ), której rozmiar różni się w zależności od architektury procesora i systemu operacyjnego ( I L P ). Klasyczna różnica: w 64-bitowym systemie operacyjnym ( kompilacja w języku Python ) długi rozmiar czcionki ( w bitach ) wynosi:

  • Nix : 64
  • Wygrana : 32

Podczas próby jego ustawienia sprawdza się, czy nowa wartość znajduje się w długich granicach, dlatego w niektórych przypadkach pojawia się inny wyjątek (ten przypadek jest powszechny w 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

Aby uniknąć tego problemu, ustaw limit (maksymalny możliwy) ( LONG_MAX ) przy użyciu sztuczki (dzięki [Python 3.Docs]: ctypes - Biblioteka funkcji obcych dla Pythona ). Powinien działać na Python 3 i Python 2 na dowolnym procesorze / systemie operacyjnym .

>>> 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'

64bit Python na Nix jak OS :

>>> 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'

W 32-bitowym Pythonie rzeczy są jednolite: takie zachowanie występuje w Win .

Sprawdź następujące zasoby, aby uzyskać więcej informacji na temat:


2

Właśnie to mi się przydarzyło w „zwykłym” pliku CSV. Niektóre osoby mogą nazwać to niepoprawnie sformatowanym plikiem. Brak znaków specjalnych, brak podwójnych cudzysłowów i separator były średnikami.

Przykładowa linia z tego pliku wyglądałaby następująco:

Pierwsza komórka; Druga „komórka z jednym podwójnym cytatem i wiodącą spacją; komórka„ Częściowo cytowana ”; ostatnia komórka

pojedynczy cytat w drugiej komórce zrzuciłby parser z szyn. Zadziałało:

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

1

Czasami wiersz zawiera kolumnę podwójnego cudzysłowu. Gdy czytnik csv spróbuje przeczytać ten wiersz, nie rozumiem końca kolumny i odpal tę podwyżkę. Rozwiązanie jest poniżej:

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

0

Możesz użyć read_csvod, pandasaby pominąć te linie.

import pandas as pd

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

Nie ma złej linii ... jak napisano w pytaniu: Pliki csv zawierają ogromne pola i te dane należy przeanalizować.
— użytkownik1251007,

1
Koncepcja złych liniipandas obejmuje wiersze przekraczające limit pola wynoszący csv. Jeśli więc chcesz pominąć te linie i przeczytać inne, możesz skorzystać z tego rozwiązania. W przeciwnym razie, gdy wymagane są ogromne pola, csv.field_size_limit(100000000)właściwe jest zwiększenie limitu pól o .
— 0x01h

-1

Znajdź plik cqlshrc zwykle umieszczony w katalogu .cassandra.

W tym pliku dołącz

[csv]
field_size_limit = 1000000000
Korzystając z naszej strony potwierdzasz, że przeczytałeś(-aś) i rozumiesz nasze zasady używania plików cookie i zasady ochrony prywatności.
Licensed under cc by-sa 3.0 with attribution required.