_csv.Error: campo maior que o limite do campo (131072)

232

Eu tenho um script lendo em um arquivo csv com campos muito 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)

No entanto, isso gera o seguinte erro em alguns arquivos csv:

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

Como posso analisar arquivos csv com campos enormes? Ignorar as linhas com campos enormes não é uma opção, pois os dados precisam ser analisados ​​nas etapas subsequentes.

user1251007
fonte
10
Melhor ainda seria considerar por que existem campos tão grandes Isso é esperado em seus dados? Às vezes, erros como esses são indicativos de um problema diferente. Eu tinha alguns dados inválidos no meu que incluíam um caractere de aspas duplas aleatórias e, portanto, tive que usar a opção QUOTE_NONE mostrada em outra resposta aqui.
dustmachine
1
Atualizei minha pergunta para indicar que, no meu caso, campos enormes podem ocorrer. Não há dados incorretos no arquivo csv.
user1251007
1
@dustmachine Essas coisas acontecem porque às vezes você encontra pessoas armazenando imagens (ou outros arquivos binários) no formato base64 nas tabelas do banco de dados.
wintermute 23/09/16

Respostas:

316

O arquivo csv pode conter campos muito grandes, portanto, aumente o field_size_limit:

import sys
import csv

csv.field_size_limit(sys.maxsize)

sys.maxsizefunciona para Python 2.xe 3.x. sys.maxintfuncionaria apenas com o Python 2.x ( SO: what-is-sys-maxint-in-python-3 )

Atualizar

Como Geoff apontou, o código acima pode resultar no seguinte erro: OverflowError: Python int too large to convert to C long. Para contornar isso, você pode usar o seguinte código rápido e sujo (que deve funcionar em todos os sistemas com 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)
user1251007
fonte
14
No Windows 7 de 64 bits com Python 2.6, maxInt = sys.maxsizeretornos 9223372036854775807Lque consequentemente resultam em uma TypeError: limit must be an integerchamada csv.field_size_limit(maxInt). Curiosamente, o uso maxInt = int(sys.maxsize)não altera isso. Uma solução alternativa é usar simplesmente o csv.field_size_limit(2147483647)que, obviamente, causa problemas em outras plataformas. No meu caso, isso foi necessário para identificar o valor quebrado no CSV, corrigir as opções de exportação no outro aplicativo e remover a necessidade csv.field_size_limit().
roskakori
muito obrigado por isso, estou tentando descobrir esse bug há séculos!
Kevin Hernandez
152

Isso pode ocorrer porque seu arquivo CSV incorporou aspas simples ou duplas. Se o seu arquivo CSV estiver delimitado por tabulação, tente abri-lo como:

c = csv.reader(f, delimiter='\t', quoting=csv.QUOTE_NONE)
CSP
fonte
1
Obrigado!! Se você estiver usando o csvkit (uma excelente biblioteca python e o kit de ferramentas csv da linha de comando) e obtiver o erro original porque seu arquivo usa aspas simples ou duplas desequilibradas, você pode selecionar QUOTE_NONE através da -u 3opção da linha de comando, aka--quoting 3
nealmcb
22

Abaixo está para verificar o limite atual

csv.field_size_limit()

Fora [20]: 131072

Abaixo está para aumentar o limite. Adicione-o ao código

csv.field_size_limit(100000000)

Tente verificar o limite novamente

csv.field_size_limit()

Fora [22]: 100000000

Agora você não receberá o erro "_csv.Error: campo maior que o limite do campo (131072)"

Tad
fonte
15

tamanhos de campo csv são controlados via [Python 3.Docs]: csv. field_size_limit ( [new_limit] ) :

Retorna o tamanho máximo atual do campo permitido pelo analisador. Se new_limit for fornecido, esse se tornará o novo limite.

É definido por padrão como 128k ou 0x20000 ( 131072 ), o que deve ser suficiente para qualquer arquivo .csv decente :

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

No entanto, ao lidar com um arquivo .csv ( com a citação e o delimitador corretos ) com (pelo menos) um campo maior que esse tamanho, o erro é exibido.
Para se livrar do erro, o limite de tamanho deve ser aumentado (para evitar preocupações, é tentado o valor máximo possível).

Nos bastidores (verifique [GitHub]: python / cpython - (mestre) cpython / Modules / _csv.c para obter detalhes da implementação), a variável que mantém esse valor é um C longo ( [Wikipedia]: tipos de dados C ), cujo tamanho varia de acordo com a arquitetura da CPU e do SO ( I L P ). A diferença clássica: para um sistema operacional de 64 bits ( compilação Python ), o tamanho do tipo longo ( em bits ) é:

  • Nix : 64
  • Vitória : 32

Ao tentar defini-lo, o novo valor é verificado para estar nos limites longos , por isso, em alguns casos, outra exceção aparece (esse caso é comum no 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 esse problema, defina o limite (máximo possível) ( LONG_MAX ) usando um artifício (graças a [Python 3.Docs]: ctypes - Uma biblioteca de funções estrangeira para Python ). Ele deve funcionar no Python 3 e Python 2 , em qualquer 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 em um Nix como sistema operacional :

>>> 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 , as coisas são uniformes: é o comportamento encontrado no Win .

Verifique os seguintes recursos para obter mais detalhes sobre:

CristiFati
fonte
2

Acabei de acontecer comigo em um arquivo CSV 'simples'. Algumas pessoas podem chamá-lo de um arquivo formatado inválido. Sem caracteres de escape, sem aspas duplas e delimitadores era um ponto e vírgula.

Uma linha de amostra desse arquivo ficaria assim:

Primeira célula; Segunda "célula com aspas duplas e espaço à esquerda; célula 'parcialmente citada'; última célula

a citação simples na segunda célula jogaria o analisador de seus trilhos. O que funcionou foi:

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

Às vezes, uma linha contém coluna de aspas duplas. Quando o leitor csv tenta ler esta linha, não entende o final da coluna e dispara esse aumento. A solução está abaixo:

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

Você pode usar read_csvfrom pandaspara pular essas linhas.

import pandas as pd

data_df = pd.read_csv('data.csv', error_bad_lines=False)
0x01h
fonte
Não existe uma linha incorreta ... como está escrito na pergunta: Os arquivos csv contêm campos enormes e esses dados precisam ser analisados.
user1251007
1
O conceito de linhas incorretas pandasinclui as linhas que excedem o limite de campos de csv. Portanto, se você quiser pular essas linhas e ler outras linhas com sucesso, poderá usar esta solução. Caso contrário, quando campos enormes forem necessários, csv.field_size_limit(100000000)é apropriado aumentar o limite de campos .
0x01h 11/11/19
-1

Localize o arquivo cqlshrc geralmente colocado no diretório .cassandra.

Nesse arquivo anexado,

[csv]
field_size_limit = 1000000000
Abdul Waseh
fonte