_csv.Error: trường lớn hơn giới hạn trường (131072)


232

Tôi có một đoạn script đọc trong tệp csv với các trường rất lớn:

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

Tuy nhiên, điều này đưa ra lỗi sau trên một số tệp csv:

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

Làm cách nào để phân tích tệp csv với các trường lớn? Bỏ qua các dòng với các trường lớn không phải là một lựa chọn vì dữ liệu cần được phân tích trong các bước tiếp theo.


10
Thậm chí tốt hơn là xem xét tại sao có những lĩnh vực lớn như vậy Điều đó có được mong đợi trong dữ liệu của bạn không? Đôi khi các lỗi như thế này là dấu hiệu của một vấn đề khác. Tôi đã có một số Dữ liệu xấu trong tôi bao gồm một ký tự trích dẫn kép ngẫu nhiên và do đó phải sử dụng tùy chọn QUOTE_NONE được hiển thị trong một câu trả lời khác ở đây.
quét bụi

1
Tôi đã cập nhật câu hỏi của mình để chỉ ra rằng trong trường hợp của tôi, các trường lớn có thể xảy ra. Không có dữ liệu xấu trong tệp csv.
dùng1251007

1
@dustmachine Những điều như vậy xảy ra bởi vì đôi khi bạn thấy mọi người lưu trữ hình ảnh (hoặc các tệp nhị phân khác) ở định dạng base64 trong các bảng cơ sở dữ liệu.
wintermute

Câu trả lời:


316

Tệp csv có thể chứa các trường rất lớn, do đó tăng field_size_limit:

import sys
import csv

csv.field_size_limit(sys.maxsize)

sys.maxsizehoạt động cho Python 2.x và 3.x. sys.maxintsẽ chỉ hoạt động với Python 2.x ( SO: what-is-sys-maxint-in-python-3 )

Cập nhật

Như Geoff đã chỉ ra, đoạn mã trên có thể dẫn đến lỗi sau : OverflowError: Python int too large to convert to C long. Để phá vỡ điều này, bạn có thể sử dụng mã nhanh và bẩn sau (mã này sẽ hoạt động trên mọi hệ thống với Python 2 và 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
Trên Windows 7 64bit với Python 2.6, maxInt = sys.maxsizetrả về 9223372036854775807Lkết quả là TypeError: limit must be an integerkhi gọi csv.field_size_limit(maxInt). Thật thú vị, sử dụng maxInt = int(sys.maxsize)không thay đổi điều này. Một cách giải quyết khác là sử dụng simlpy csv.field_size_limit(2147483647), điều này tất nhiên gây ra sự cố trên các nền tảng khác. Trong trường hợp của tôi, đây là adquat để xác định giá trị bị hỏng trong CSV, sửa các tùy chọn xuất trong ứng dụng khác và loại bỏ sự cần thiết csv.field_size_limit().
roskakori

cảm ơn bạn rất nhiều vì điều này, tôi đã cố gắng tìm ra lỗi này từ lâu!
Kevin Hernandez

152

Điều này có thể là do tệp CSV của bạn đã nhúng dấu ngoặc đơn hoặc dấu ngoặc kép. Nếu tệp CSV của bạn được phân định bằng tab, hãy thử mở nó dưới dạng:

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

1
Cảm ơn bạn!! Nếu bạn đang sử dụng csvkit (thư viện python và bộ công cụ csv dòng lệnh tuyệt vời) và gặp lỗi ban đầu vì tệp của bạn sử dụng dấu ngoặc đơn hoặc dấu ngoặc kép không cân bằng, bạn có thể chọn QUOTE_NONE thông qua -u 3tùy chọn dòng lệnh, còn gọi là--quoting 3
nealmcb

22

Dưới đây là để kiểm tra giới hạn hiện tại

csv.field_size_limit()

Hết [20]: 131072

Dưới đây là để tăng giới hạn. Thêm nó vào mã

csv.field_size_limit(100000000)

Hãy thử kiểm tra lại giới hạn

csv.field_size_limit()

Hết [22]: 100000000

Bây giờ bạn sẽ không gặp lỗi "_csv.Error: trường lớn hơn giới hạn trường (131072)"


15

kích thước trường csv được điều khiển thông qua [Python 3.Docs]: csv. trường_size_limit ( [new_limit] ) :

Trả về kích thước trường tối đa hiện tại được cho phép bởi trình phân tích cú pháp. Nếu new_limit được đưa ra, điều này trở thành giới hạn mới.

Nó được đặt theo mặc định là 128k hoặc 0x20000 ( 131072 ), mức này đủ cho bất kỳ .csv nào :

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

Tuy nhiên, khi xử lý tệp .csv ( với trích dẫndấu phân cách chính xác ) có (ít nhất) một trường dài hơn kích thước này, lỗi sẽ bật lên.
Để thoát khỏi lỗi, nên tăng giới hạn kích thước (để tránh mọi lo lắng, giá trị tối đa có thể được thử).

Đằng sau hậu trường (kiểm tra [GitHub]: python / cpython - (master) cpython / Modules / _csv.c để biết chi tiết triển khai), biến giữ giá trị này là một C dài ( [Wikipedia]: Kiểu dữ liệu C ), có kích thước thay đổi tùy theo kiến trúc CPUHĐH ( I L P ). Sự khác biệt cổ điển: đối với HĐH 64 bit (bản dựng Python ), kích thước loại dài (tính bằng bit ) là:

  • Nix : 64
  • Thắng : 32

Khi cố gắng đặt nó, giá trị mới được kiểm tra ở các ranh giới dài , đó là lý do tại sao trong một số trường hợp, một ngoại lệ khác xuất hiện (trường hợp này là phổ biến trên 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

Để tránh gặp phải vấn đề này, hãy đặt giới hạn (tối đa có thể) ( LONG_MAX ) bằng cách sử dụng một tạo phẩm (nhờ [Python 3.Docs]: ctypes - Thư viện hàm nước ngoài cho Python ). Nó nên hoạt động trên Python 3Python 2 , trên bất kỳ CPU / HĐH nào .

>>> 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 bit trên Nix như HĐH :

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

Đối với Python 32 bit , mọi thứ đều thống nhất: đó là hành vi gặp phải trên Win .

Kiểm tra các tài nguyên sau để biết thêm chi tiết về:


2

Tôi chỉ có điều này xảy ra với tôi trên tệp CSV 'đơn giản'. Một số người có thể gọi nó là một tập tin định dạng không hợp lệ. Không có ký tự thoát, không có dấu ngoặc kép và dấu phân cách là dấu chấm phẩy.

Một dòng mẫu từ tệp này sẽ trông như thế này:

Tế bào đầu tiên; Thứ hai "Ô có một trích dẫn kép và không gian hàng đầu; ô" Trích dẫn một phần "; Ô cuối cùng

trích dẫn duy nhất trong ô thứ hai sẽ ném trình phân tích cú pháp ra khỏi đường ray của nó. Những gì đã làm việc là:

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

1

Đôi khi, một hàng chứa cột trích dẫn kép. Khi người đọc csv thử đọc hàng này, không hiểu cuối cột và kích hoạt tăng này. Giải pháp dưới đây:

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

0

Bạn có thể sử dụng read_csvtừ pandasđể bỏ qua những dòng này.

import pandas as pd

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

Không có dòng nào xấu ... như được viết trong câu hỏi: Các tệp csv chứa các trường lớn và dữ liệu này cần được phân tích.
dùng1251007

1
Khái niệm dòng xấu trong pandasbao gồm các hàng vượt quá giới hạn trường csv. Vì vậy, nếu bạn muốn bỏ qua các dòng này và đọc các dòng khác thành công, bạn có thể sử dụng giải pháp này. Mặt khác, khi các trường lớn được yêu cầu cho bạn, tăng giới hạn trường csv.field_size_limit(100000000)là phù hợp.
0x01h

-1

Tìm tập tin cqlshrc thường được đặt trong thư mục .cassandra.

Trong tập tin đó nối thêm,

[csv]
field_size_limit = 1000000000
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.