_csv.Error: campo più grande del limite di campo (131072)


232

Ho uno script che legge in un file CSV con campi molto grandi:

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

Tuttavia, ciò genera il seguente errore su alcuni file CSV:

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

Come posso analizzare i file CSV con campi enormi? Saltare le linee con enormi campi non è un'opzione in quanto i dati devono essere analizzati nelle fasi successive.


10
Ancora meglio sarebbe considerare perché ci sono campi così grandi È previsto nei tuoi dati? A volte errori come questi sono indicativi di un problema diverso. Avevo alcuni dati errati nei miei che includevano un carattere a virgoletta doppia casuale e quindi dovevo usare l'opzione QUOTE_NONE mostrata in un'altra risposta qui.
polvere

1
Ho aggiornato la mia domanda per indicare che nel mio caso potrebbero verificarsi enormi campi. Non ci sono dati errati nel file CSV.
user1251007,

1
@dustmachine Queste cose accadono perché a volte trovi persone che memorizzano immagini (o altri file binari) in formato base64 nelle tabelle del database.
Wintermute,

Risposte:


316

Il file CSV potrebbe contenere campi molto grandi, quindi aumentare il field_size_limit:

import sys
import csv

csv.field_size_limit(sys.maxsize)

sys.maxsizefunziona per Python 2.xe 3.x. sys.maxintfunzionerebbe solo con Python 2.x ( SO: what-is-sys-maxint-in-python-3 )

Aggiornare

Come Geoff ha sottolineato, il codice di cui sopra potrebbe comportare l'errore seguente: OverflowError: Python int too large to convert to C long. Per aggirare questo, è possibile utilizzare il seguente codice rapido e sporco (che dovrebbe funzionare su tutti i sistemi con Python 2 e 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
Su Windows 7 a 64 bit con Python 2.6, maxInt = sys.maxsizerestituisce il 9223372036854775807Lrisultato che si traduce di conseguenza in una TypeError: limit must be an integerchiamata csv.field_size_limit(maxInt). È interessante notare che l'utilizzo maxInt = int(sys.maxsize)non cambia questo. Una soluzione approssimativa è quella di semplificare l'uso csv.field_size_limit(2147483647)che ovviamente causa problemi su altre piattaforme. Nel mio caso, questo è stato un problema per identificare il valore rotto nel CSV, correggere le opzioni di esportazione nell'altra applicazione e rimuovere la necessità csv.field_size_limit().
Roskakori,

grazie mille per questo, sto provando a capire questo bug da secoli!
Kevin Hernandez,

152

Ciò potrebbe essere dovuto al fatto che il file CSV ha virgolette singole o doppie incorporate. Se il tuo file CSV è delimitato da tabulazioni, prova ad aprirlo come:

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

1
Grazie!! Se stai usando csvkit (un'eccellente libreria python e toolkit csv da riga di comando) e ottieni l'errore originale perché il tuo file utilizza virgolette singole o doppie non bilanciate, puoi selezionare QUOTE_NONE tramite l' -u 3opzione della riga di comando, aka--quoting 3
nealmcb

22

Di seguito è verificare il limite corrente

csv.field_size_limit()

Out [20]: 131072

Di seguito è aumentare il limite. Aggiungilo al codice

csv.field_size_limit(100000000)

Prova a controllare di nuovo il limite

csv.field_size_limit()

Out [22]: 100000000

Ora non verrà visualizzato l'errore "_csv.Error: campo più grande del limite del campo (131072)"


15

Le dimensioni dei campi CSV sono controllate tramite [Python 3.Docs]: CSV. field_size_limit ( [new_limit] ) :

Restituisce la dimensione massima del campo corrente consentita dal parser. Se viene dato new_limit , questo diventa il nuovo limite.

L'impostazione predefinita è 128k o 0x20000 ( 131072 ), che dovrebbe essere sufficiente per qualsiasi .csv decente :

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

Tuttavia, quando si ha a che fare con un file .csv ( con virgolette e delimitatori corretti ) con (almeno) un campo più lungo di questa dimensione, viene visualizzato l'errore.
Per eliminare l'errore, è necessario aumentare il limite di dimensioni (per evitare qualsiasi preoccupazione, si tenta il valore massimo possibile).

Dietro le quinte (selezionare [GitHub]: python / cpython - (master) cpython / Modules / _csv.c per i dettagli di implementazione), la variabile che contiene questo valore è una C lunga ( [Wikipedia]: tipi di dati C ), le cui dimensioni varia a seconda dell'architettura della CPU e del sistema operativo ( I L P ). La differenza classica: per un sistema operativo a 64 bit ( build Python ), la dimensione del tipo lungo ( in bit ) è:

  • Nix : 64
  • Vinci : 32

Quando si tenta di impostarlo, viene verificato che il nuovo valore sia lungo i limiti, ecco perché in alcuni casi viene visualizzata un'altra eccezione (questo caso è comune su 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

Per evitare di incorrere in questo problema, impostare il limite (massimo possibile) ( LONG_MAX ) usando un artificio (grazie a [Python 3.Docs]: ctypes - Una libreria di funzioni esterne per Python ). Dovrebbe funzionare su Python 3 e Python 2 , su qualsiasi CPU / sistema operativo .

>>> 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 bit Python su un sistema operativo Nix come :

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

Per Python a 32 bit , le cose sono uniformi: è il comportamento riscontrato su Win .

Controlla le seguenti risorse per maggiori dettagli su:


2

Mi è appena successo questo in un file CSV "semplice". Alcune persone potrebbero chiamarlo un file formattato non valido. Nessun carattere di escape, nessuna doppia virgoletta e delimitatore era un punto e virgola.

Una riga di esempio da questo file sarebbe simile a questa:

Prima cella; Seconda "Cella con una doppia citazione e spazio iniziale; cella" Parzialmente quotata "; Ultima cella

la singola citazione nella seconda cella avrebbe gettato il parser dalle sue guide. Ciò che ha funzionato è stato:

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

1

A volte, una riga contiene una colonna con virgolette doppie. Quando il lettore CSV prova a leggere questa riga, non capisce la fine della colonna e lancia questo rilancio. La soluzione è di seguito:

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

0

Puoi usare read_csvda pandasper saltare queste righe.

import pandas as pd

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

Non c'è una linea sbagliata ... come scritto nella domanda: i file CSV contengono campi enormi e questi dati devono essere analizzati.
user1251007

1
Il concetto di linee errate pandasinclude le righe che superano il limite di campo di csv. Pertanto, se si desidera saltare queste righe e leggere correttamente altre righe, è possibile utilizzare questa soluzione. Altrimenti, quando sono richiesti enormi campi per te, csv.field_size_limit(100000000)è appropriato aumentare il limite di campo di .
0x01h,

-1

Trova il file cqlshrc solitamente posizionato nella directory .cassandra.

In quel file append,

[csv]
field_size_limit = 1000000000
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.