_csv.Error: bidang lebih besar dari batas bidang (131072)

232

Saya memiliki skrip yang dibaca dalam file csv dengan bidang yang sangat besar:

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

Namun, ini melempar kesalahan berikut pada beberapa file csv:

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

Bagaimana saya bisa menganalisis file csv dengan bidang besar? Melewati garis dengan bidang besar bukanlah pilihan karena data perlu dianalisis dalam langkah-langkah selanjutnya.

pengguna1251007
sumber
10
Bahkan lebih baik mempertimbangkan mengapa ada bidang besar seperti itu Apakah itu diharapkan dalam data Anda? Terkadang kesalahan seperti ini menunjukkan masalah yang berbeda. Saya memiliki beberapa Data Buruk di tambang yang menyertakan karakter kutipan ganda acak dan karenanya harus menggunakan opsi QUOTE_NONE yang ditampilkan dalam jawaban lain di sini.
dustmachine
1
Saya memperbarui pertanyaan saya untuk menunjukkan bahwa dalam kasus saya bidang besar mungkin terjadi. Tidak ada data buruk di file csv.
user1251007
1
@dustmachine Hal-hal seperti itu terjadi karena kadang-kadang Anda menemukan orang menyimpan gambar (atau file biner lainnya) dalam format base64 dalam tabel database.
musim dingin

Jawaban:

316

File csv mungkin berisi bidang yang sangat besar, oleh karena itu tingkatkan field_size_limit:

import sys
import csv

csv.field_size_limit(sys.maxsize)

sys.maxsizebekerja untuk Python 2.x dan 3.x. sys.maxinthanya akan bekerja dengan Python 2.x ( SO: what-is-sys-maxint-in-python-3 )

Memperbarui

Sebagai Geoff menunjukkan, kode di atas mungkin mengakibatkan kesalahan berikut: OverflowError: Python int too large to convert to C long. Untuk menghindari hal ini, Anda dapat menggunakan kode cepat dan kotor berikut (yang harus bekerja pada setiap sistem dengan Python 2 dan 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)
pengguna1251007
sumber
14
Pada Windows 7 64bit dengan Python 2.6, maxInt = sys.maxsizemengembalikan 9223372036854775807Lyang akibatnya menghasilkan TypeError: limit must be an integerpanggilan saat csv.field_size_limit(maxInt). Menariknya, menggunakan maxInt = int(sys.maxsize)tidak mengubah ini. Solusi kasarnya adalah menggunakan simlpy csv.field_size_limit(2147483647)yang tentu saja menyebabkan masalah pada platform lain. Dalam kasus saya ini cukup untuk mengidentifikasi nilai yang rusak di CSV, memperbaiki opsi ekspor di aplikasi lain dan menghapus kebutuhan csv.field_size_limit().
roskakori
terima kasih banyak untuk ini, saya sudah mencoba untuk mencari tahu bug ini selama bertahun-tahun!
Kevin Hernandez
152

Ini bisa jadi karena file CSV Anda telah menyertakan tanda kutip tunggal atau ganda. Jika file CSV Anda dibatasi-tab, coba buka sebagai:

c = csv.reader(f, delimiter='\t', quoting=csv.QUOTE_NONE)
CSP
sumber
1
Terima kasih!! Jika Anda menggunakan csvkit (pustaka python yang sangat baik dan csv toolkit baris-perintah) dan mendapatkan kesalahan asli karena file Anda menggunakan tanda kutip tunggal atau ganda yang tidak seimbang, Anda dapat memilih QUOTE_NONE melalui -u 3opsi baris perintah, alias--quoting 3
nealmcb
22

Di bawah ini untuk memeriksa batas saat ini

csv.field_size_limit()

Keluar [20]: 131072

Di bawah ini untuk meningkatkan batas. Tambahkan ke kode

csv.field_size_limit(100000000)

Coba periksa lagi batasnya

csv.field_size_limit()

Keluar [22]: 100000000

Sekarang Anda tidak akan mendapatkan kesalahan "_csv.Error: bidang lebih besar dari batas bidang (131072)"

Tad
sumber
15

Ukuran bidang csv dikendalikan melalui [Python 3.Docs]: csv. field_size_limit ( [new_limit] ) :

Mengembalikan ukuran bidang maksimum saat ini yang diizinkan oleh pengurai. Jika new_limit diberikan, ini menjadi batas baru.

Ini diatur secara default ke 128k atau 0x20000 ( 131072 ), yang seharusnya cukup untuk .csv yang layak :

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

Namun, ketika berurusan dengan file .csv ( dengan kutipan dan pembatas yang benar ) memiliki (setidaknya) satu bidang lebih panjang dari ukuran ini, kesalahan muncul.
Untuk menghilangkan kesalahan, batas ukuran harus ditingkatkan (untuk menghindari kekhawatiran, nilai maksimum yang mungkin dicoba).

Di belakang layar (centang [GitHub]: python / cpython - (master) cpython / Modul / _csv.c untuk detail implementasi), variabel yang memegang nilai ini adalah C panjang ( [Wikipedia]: tipe data C ), yang ukurannya bervariasi tergantung pada arsitektur CPU dan OS ( I L P ). Perbedaan klasik: untuk OS 64bit ( Python build), ukuran tipe panjang ( dalam bit ) adalah:

  • Nix : 64
  • Menangkan : 32

Ketika mencoba untuk mengaturnya, nilai baru diperiksa berada dalam batas-batas panjang , itu sebabnya dalam beberapa kasus pengecualian lain muncul (kasus ini umum pada 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

Untuk menghindari masalah ini, setel batas (maksimum yang mungkin) ( LONG_MAX ) menggunakan artifice (terima kasih kepada [Python 3.Docs]: ctypes - Pustaka fungsi asing untuk Python ). Ini harus bekerja pada Python 3 dan Python 2 , pada CPU / OS apa pun .

>>> 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 pada Nix seperti 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'

Untuk 32bit Python , semuanya seragam: itu adalah perilaku yang ditemui pada Win .

Periksa sumber daya berikut untuk detail lebih lanjut tentang:

CristiFati
sumber
2

Saya baru saja mengalami hal ini pada saya di file CSV 'biasa'. Beberapa orang mungkin menyebutnya file berformat tidak valid. Tidak ada karakter melarikan diri, tidak ada tanda kutip ganda dan pembatas adalah titik koma.

Baris sampel dari file ini akan terlihat seperti ini:

Sel pertama; Kedua "Sel dengan satu kutip ganda dan ruang terdepan; sel 'Sebagian dikutip'; Sel terakhir

kutipan tunggal di sel kedua akan membuang pengurai dari relnya. Apa yang berhasil adalah:

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

Terkadang, satu baris berisi kolom kutipan ganda. Ketika pembaca csv mencoba membaca baris ini, tidak mengerti akhir kolom dan jalankan kenaikan ini. Solusinya di bawah:

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

Anda dapat menggunakan read_csvdari pandasuntuk melewati garis-garis ini.

import pandas as pd

data_df = pd.read_csv('data.csv', error_bad_lines=False)
0x01j
sumber
Tidak ada garis buruk ... seperti yang tertulis dalam pertanyaan: File csv berisi bidang yang sangat besar dan data ini perlu dianalisis.
user1251007
1
Konsep garis buruk di pandasmencakup baris yang melebihi batas bidang csv. Jadi, jika Anda ingin melewati baris ini dan membaca baris lainnya dengan sukses, Anda dapat menggunakan solusi ini. Jika tidak, ketika bidang besar diperlukan untuk Anda, meningkatkan batas bidang menurut csv.field_size_limit(100000000)adalah tepat.
0x01j
-1

Temukan file cqlshrc yang biasanya ditempatkan di direktori .cassandra.

Dalam file yang ditambahkan,

[csv]
field_size_limit = 1000000000
Abdul Waseh
sumber