_csv.Error: champ supérieur à la limite de champ (131072)

232

J'ai un script qui lit dans un fichier csv avec des champs très énormes:

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

Cependant, cela génère l'erreur suivante sur certains fichiers csv:

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

Comment puis-je analyser des fichiers csv avec des champs énormes? Sauter les lignes avec des champs énormes n'est pas une option car les données doivent être analysées dans les étapes suivantes.

user1251007
la source
10
Mieux encore serait de se demander pourquoi il y a de si grands champs. Est-ce prévu dans vos données? Parfois, des erreurs comme celles-ci indiquent un problème différent. J'avais quelques mauvaises données dans le mien qui comprenaient un caractère de guillemet double aléatoire et j'ai donc dû utiliser l'option QUOTE_NONE indiquée dans une autre réponse ici.
dustmachine
1
J'ai mis à jour ma question pour indiquer que dans mon cas, des champs énormes pourraient se produire. Il n'y a pas de mauvaises données dans le fichier csv.
user1251007
1
@dustmachine De telles choses se produisent parce que parfois des personnes stockent des images (ou d'autres fichiers binaires) au format base64 dans des tables de base de données.
Wintermute

Réponses:

316

Le fichier csv peut contenir des champs très volumineux, augmentez donc field_size_limit:

import sys
import csv

csv.field_size_limit(sys.maxsize)

sys.maxsizefonctionne pour Python 2.x et 3.x. sys.maxintne fonctionnerait qu'avec Python 2.x ( SO: what-is-sys-maxint-in-python-3 )

Mettre à jour

Comme Geoff a fait remarquer, le code ci - dessus pourrait entraîner l'erreur suivante: OverflowError: Python int too large to convert to C long. Pour contourner cela, vous pouvez utiliser le code rapide et sale suivant (qui devrait fonctionner sur tous les systèmes avec Python 2 et 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)
user1251007
la source
14
Sur Windows 7 64 bits avec Python 2.6, maxInt = sys.maxsizerenvoie 9223372036854775807Lce qui entraîne par conséquent un TypeError: limit must be an integerlors de l'appel csv.field_size_limit(maxInt). Fait intéressant, l'utilisation maxInt = int(sys.maxsize)ne change pas cela. Une solution de contournement grossière consiste à simplifier l'utilisation, csv.field_size_limit(2147483647)ce qui bien sûr cause des problèmes sur d'autres plates-formes. Dans mon cas, c'était suffisant pour identifier la valeur cassée dans le CSV, corriger les options d'exportation dans l'autre application et supprimer le besoin de csv.field_size_limit().
roskakori
merci beaucoup pour cela, j'ai essayé de comprendre ce bug depuis des lustres!
Kevin Hernandez
152

Cela peut être dû au fait que votre fichier CSV a incorporé des guillemets simples ou doubles. Si votre fichier CSV est délimité par des tabulations, essayez de l'ouvrir en tant que:

c = csv.reader(f, delimiter='\t', quoting=csv.QUOTE_NONE)
CSP
la source
1
Je vous remercie!! Si vous utilisez csvkit (une excellente bibliothèque python et une boîte à outils csv en ligne de commande) et obtenez l'erreur d'origine parce que votre fichier utilise des guillemets simples ou doubles asymétriques, vous pouvez sélectionner QUOTE_NONE via l' -u 3option de ligne de commande, aka--quoting 3
nealmcb
22

Ci-dessous est de vérifier la limite actuelle

csv.field_size_limit()

Sortie [20]: 131072

Ci-dessous est d'augmenter la limite. Ajoutez-le au code

csv.field_size_limit(100000000)

Essayez de vérifier à nouveau la limite

csv.field_size_limit()

Sortie [22]: 100000000

Maintenant, vous n'obtiendrez pas l'erreur "_csv.Error: champ plus grand que la limite de champ (131072)"

Tad
la source
15

La taille des champs csv est contrôlée via [Python 3.Docs]: csv. field_size_limit ( [new_limit] ) :

Renvoie la taille de champ maximale actuelle autorisée par l'analyseur. Si new_limit est donné, cela devient la nouvelle limite.

Il est défini par défaut sur 128k ou 0x20000 ( 131072 ), ce qui devrait être suffisant pour tout .csv décent :

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

Cependant, lorsque vous traitez un fichier .csv ( avec les guillemets et délimiteurs corrects ) ayant (au moins) un champ plus long que cette taille, l'erreur apparaît.
Pour se débarrasser de l'erreur, la taille limite doit être augmentée (pour éviter tout souci, la valeur maximale possible est tentée).

Dans les coulisses (vérifiez [GitHub]: python / cpython - (maître) cpython / Modules / _csv.c pour les détails d'implémentation), la variable qui contient cette valeur est un C long ( [Wikipedia]: types de données C ), dont la taille varie en fonction de l' architecture du processeur et du système d'exploitation ( I L P ). La différence classique: pour un OS 64 bits ( build Python ), la taille de type long ( en bits ) est:

  • Nix : 64
  • Victoires : 32

Lorsque vous tentez de le définir, la nouvelle valeur est vérifiée pour être dans les limites longues , c'est pourquoi dans certains cas, une autre exception apparaît (ce cas est courant sur 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

Pour éviter de rencontrer ce problème, définissez la limite (maximale possible) ( LONG_MAX ) à l'aide d'un artifice (grâce à [Python 3.Docs]: ctypes - Une bibliothèque de fonctions étrangères pour Python ). Il devrait fonctionner sur Python 3 et Python 2 , sur n'importe quel 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 64 bits sur un système d'exploitation comme 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'

Pour Python 32 bits , les choses sont uniformes: c'est le comportement rencontré sur Win .

Consultez les ressources suivantes pour plus de détails sur:

CristiFati
la source
2

Je venais juste de m'arriver sur un fichier CSV «simple». Certaines personnes pourraient l'appeler un fichier formaté non valide. Pas de caractères d'échappement, pas de guillemets doubles et le délimiteur était un point-virgule.

Un exemple de ligne de ce fichier ressemblerait à ceci:

Première cellule; Deuxième "cellule avec un guillemet double et un espace de tête; cellule" partiellement citée "; dernière cellule

la citation unique dans la deuxième cellule jetterait l'analyseur de ses rails. Ce qui a fonctionné était:

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

Parfois, une ligne contient une colonne de guillemets doubles. Lorsque le lecteur csv essaie de lire cette ligne, la fin de la colonne n'est pas comprise et déclenche cette augmentation. La solution est ci-dessous:

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

Vous pouvez utiliser read_csvfrom pandaspour ignorer ces lignes.

import pandas as pd

data_df = pd.read_csv('data.csv', error_bad_lines=False)
0x01h
la source
Il n'y a pas de mauvaise ligne ... comme écrit dans la question: les fichiers csv contiennent des champs énormes et ces données doivent être analysées.
user1251007
1
Le concept de mauvaises lignespandas inclut les lignes qui dépassent la limite de champ de csv. Donc, si vous souhaitez ignorer ces lignes et lire d'autres lignes avec succès, vous pouvez utiliser cette solution. Sinon, lorsque des champs énormes vous sont nécessaires, l'augmentation de la limite de champ de csv.field_size_limit(100000000)est appropriée.
0x01h
-1

Recherchez le fichier cqlshrc généralement placé dans le répertoire .cassandra.

Dans ce fichier,

[csv]
field_size_limit = 1000000000
Abdul Waseh
la source