_csv.Error: campo mayor que el límite de campo (131072)

232

Tengo un script que lee en un archivo csv con campos muy grandes:

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

Sin embargo, esto arroja el siguiente error en algunos archivos csv:

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

¿Cómo puedo analizar archivos csv con grandes campos? Saltar las líneas con campos enormes no es una opción, ya que los datos deben analizarse en los pasos posteriores.

usuario1251007
fuente
10
Aún mejor sería considerar por qué hay campos tan grandes ¿Se espera eso en sus datos? A veces, errores como estos son indicativos de un problema diferente. Tenía algunos datos malos en la mía que incluían un carácter de comillas dobles al azar y, por lo tanto, tuve que usar la opción QUOTE_NONE que se muestra en otra respuesta aquí.
dustmachine
1
Actualicé mi pregunta para indicar que en mi caso podrían producirse campos enormes. No hay datos incorrectos en el archivo csv.
user1251007
1
@dustmachine Estas cosas suceden porque a veces se encuentran personas que almacenan imágenes (u otros archivos binarios) en formato base64 en tablas de bases de datos.
wintermute

Respuestas:

316

El archivo csv puede contener campos muy grandes, por lo tanto, aumente field_size_limit:

import sys
import csv

csv.field_size_limit(sys.maxsize)

sys.maxsizefunciona para Python 2.xy 3.x. sys.maxintsolo funcionaría con Python 2.x ( SO: what-is-sys-maxint-in-python-3 )

Actualizar

Como se señaló Geoff, el código anterior podría resultar en el siguiente error: OverflowError: Python int too large to convert to C long. Para evitar esto, puede usar el siguiente código rápido y sucio (que debería funcionar en todos los sistemas con Python 2 y 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)
usuario1251007
fuente
14
En Windows 7 de 64 bits con Python 2.6, maxInt = sys.maxsizedevuelve lo 9223372036854775807Lque en consecuencia da como resultado una TypeError: limit must be an integerllamada csv.field_size_limit(maxInt). Curiosamente, el uso maxInt = int(sys.maxsize)no cambia esto. Una solución alternativa cruda es el uso simple csv.field_size_limit(2147483647)que, por supuesto, causa problemas en otras plataformas. En mi caso, esto se adquirió para identificar el valor roto en el CSV, corregir las opciones de exportación en la otra aplicación y eliminar la necesidad de csv.field_size_limit().
roskakori
¡Muchas gracias por esto, he estado tratando de resolver este error durante años!
Kevin Hernández
152

Esto podría deberse a que su archivo CSV tiene comillas simples o dobles incrustadas. Si su archivo CSV está delimitado por tabulaciones, intente abrirlo como:

c = csv.reader(f, delimiter='\t', quoting=csv.QUOTE_NONE)
CSP
fuente
1
¡¡Gracias!! Si está utilizando csvkit (una excelente biblioteca de Python y un kit de herramientas csv de línea de comandos) y obtiene el error original porque su archivo utiliza comillas simples o dobles no balanceadas, puede seleccionar QUOTE_NONE a través de la -u 3opción de línea de comandos, también conocido como--quoting 3
nealmcb
22

A continuación se muestra el límite actual.

csv.field_size_limit()

Fuera [20]: 131072

A continuación se muestra para aumentar el límite. Agréguelo al código

csv.field_size_limit(100000000)

Intenta verificar el límite nuevamente

csv.field_size_limit()

Fuera [22]: 100000000

Ahora no obtendrá el error "_csv.Error: campo mayor que el límite de campo (131072)"

Tad
fuente
15

Los tamaños de campo csv se controlan a través de [Python 3.Docs]: csv. field_size_limit ( [new_limit] ) :

Devuelve el tamaño de campo máximo actual permitido por el analizador. Si se da new_limit , este se convierte en el nuevo límite.

Está configurado de forma predeterminada en 128k o 0x20000 ( 131072 ), lo que debería ser suficiente para cualquier .csv decente:

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

Sin embargo, cuando se trata de un archivo .csv ( con el delimitador y las comillas correctas ) que tiene (al menos) un campo más largo que este tamaño, aparece el error.
Para deshacerse del error, se debe aumentar el límite de tamaño (para evitar preocupaciones, se intenta el valor máximo posible).

Detrás de escena (marque [GitHub]: python / cpython - (master) cpython / Modules / _csv.c para detalles de implementación), la variable que contiene este valor es una C larga ( [Wikipedia]: tipos de datos C ), cuyo tamaño varía según la arquitectura de la CPU y el sistema operativo ( I L P ). La diferencia clásica: para un 64bit SO de ( compilación de Python ), el tamaño de letra largo ( en bits ) es:

  • Nix : 64
  • Victoria : 32

Al intentar establecerlo, se verifica que el nuevo valor esté en límites largos , por eso en algunos casos aparece otra excepción (este caso es común en 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

Para evitar encontrarse con este problema, establezca el límite (máximo posible) ( LONG_MAX ) utilizando un artificio (gracias a [Python 3.Docs]: ctypes - Una biblioteca de funciones foráneas para Python ). Debería funcionar en Python 3 y Python 2 , en cualquier CPU / OS .

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

Python de 64 bits en un Nix como SO :

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

Para Python de 32 bits , las cosas son uniformes: es el comportamiento encontrado en Win .

Consulte los siguientes recursos para obtener más detalles sobre:

CristiFati
fuente
2

Me acaba de suceder esto en un archivo CSV 'normal'. Algunas personas pueden llamarlo un archivo con formato no válido. Sin caracteres de escape, sin comillas dobles y delimitador era un punto y coma.

Una línea de muestra de este archivo se vería así:

Primera celda; Segunda "celda con una comilla doble y espacio inicial; celda 'Parcialmente citada'; última celda

la comilla simple en la segunda celda arrojaría al analizador de sus rieles. Lo que funcionó fue:

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

A veces, una fila contiene una columna de comillas dobles. Cuando el lector csv intente leer esta fila, no se comprende el final de la columna y dispare este aumento. La solución está abajo:

reader = csv.reader(cf, quoting=csv.QUOTE_MINIMAL)
Ahmet Erkan ÇELİK
fuente
0

Puede usar read_csvdesde pandaspara omitir estas líneas.

import pandas as pd

data_df = pd.read_csv('data.csv', error_bad_lines=False)
0x01h
fuente
No hay una línea incorrecta ... como está escrito en la pregunta: los archivos csv contienen campos enormes y estos datos deben analizarse.
user1251007
1
El concepto de líneas incorrectaspandas incluye las filas que exceden el límite de campo de csv. Por lo tanto, si desea omitir estas líneas y leer otras líneas con éxito, puede usar esta solución. De lo contrario, cuando se requieren campos enormes para usted, csv.field_size_limit(100000000)es apropiado aumentar el límite de campo en .
0x01h
-1

Busque el archivo cqlshrc que generalmente se encuentra en el directorio .cassandra.

En ese archivo adjunto,

[csv]
field_size_limit = 1000000000
Abdul Waseh
fuente