_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.