_csv。错误:字段大于字段限制(131072)

我有一个脚本在csv文件中读取非常大的字段:

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

但是,这会在一些csv文件上抛出以下错误:

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

我如何分析具有巨大字段的csv文件?跳过具有大字段的行是不可取的,因为数据需要在后续步骤中进行分析。

179020 次浏览

csv文件可能包含非常大的字段,因此增加field_size_limit:

import sys
import csv


csv.field_size_limit(sys.maxsize)

sys.maxsize适用于Python 2。X和3.x。sys.maxint只适用于python2。x (所以:what-is-sys-maxint-in-python-3)

更新

正如Geoff所指出的,上面的代码可能会导致以下错误:OverflowError: Python int too large to convert to C long。 为了避免这种情况,你可以使用以下又快又脏代码(它应该适用于Python 2和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)

这可能是因为您的CSV文件嵌入了单引号或双引号。如果您的CSV文件是制表符分隔的,请尝试以以下方式打开:

c = csv.reader(f, delimiter='\t', quoting=csv.QUOTE_NONE)
有时,一行包含双引号列。当csv读取器尝试读取该行时,不理解列的末尾并触发此引发。 解决方法如下:

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

下面是检查当前的限制

csv.field_size_limit()

出[20]:131072

下面是增加限制。将其添加到代码中

csv.field_size_limit(100000000)

试着再检查一下极限

csv.field_size_limit()

出[22]:100000000

现在您将不会得到错误“_csv”。错误:字段大于字段限制(131072)"

找到通常放在.cassandra目录下的cqlshrc文件。

在那个文件中追加,

[csv]
field_size_limit = 1000000000

. csv字段大小通过(Python。文档:csv.field_size_limit ([new_limit])来控制(强调是我的):

返回解析器允许的当前最大字段大小。如果new_limit,这将成为新的限制

它默认设置为<强> 131072 < / >强<强> 0 x20000 < / >强 (128 k),这对于任何像样的. csv应该足够了:

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

但是,当处理的. csv文件(使用正确的引用和分隔符)的字段(至少)比这个大小长一个时,就会弹出错误。
为了消除错误,应该增加大小限制(为了避免任何担忧,尝试最大可能的值)。

在幕后(查看[GitHub]: python/cpython - (master) cpython/Modules/_csv.c获取实现细节),保存该值的变量是C <强>长< / >强 ([维基百科]:C数据类型),其大小为取决于CPU架构和OS (L我< > < / >强P)。经典的区别:对于<强> 064位< / >强 操作系统(和Python构建),类型大小(在比特)为:

  • 女水妖: <强> 64 < / >强
  • 赢得: <强> 32 < / >强

当尝试设置它时,新值会被检查是否在边界内,这就是为什么在某些情况下会弹出另一个异常(因为sys.maxsize通常在赢得上遇到064位宽):

>>> import sys, ctypes as ct
>>>
>>>
>>> "v{:d}.{:d}.{:d}".format(*sys.version_info[:3]), sys.platform, sys.maxsize, ct.sizeof(ct.c_void_p) * 8, ct.sizeof(ct.c_long) * 8
('v3.9.9', 'win32', 9223372036854775807, 64, 32)
>>>
>>> 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

为了避免遇到这个问题,设置(最大可能的)限制(< >强LONG_MAX < / >强), 使用技巧(感谢(Python。ctypes - Python的外部函数库)。它应该适用于Python 3Python 2,适用于任何CPU / 操作系统

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

操作系统这样的女水妖上的064位 Python:

>>> import sys, csv, ctypes as ct
>>>
>>>
>>> "v{:d}.{:d}.{:d}".format(*sys.version_info[:3]), sys.platform, sys.maxsize, ct.sizeof(ct.c_void_p) * 8, ct.sizeof(ct.c_long) * 8
('v3.8.10', 'linux', 9223372036854775807, 64, 64)
>>>
>>> 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'

对于032位 Python,事情应该在没有技巧的情况下顺利运行(因为sys.maxsizeLONG_MAX都是032位宽的)。如果这个最大值仍然不够,那么. csv将需要人工干预才能从Python被处理。

查看以下资源了解更多详细信息:

我刚刚在一个“普通”CSV文件上发生了这种情况。有些人可能称其为无效格式化文件。没有转义字符,没有双引号,分隔符是分号。

该文件的示例行如下所示:

< p >第一个细胞;第二个“Cell”带有双引号和前导 空格;'部分引用'单元格;最后一个单元格

第二个单元格中的单引号会使解析器偏离轨道。奏效的方法是:

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

你可以使用pd.read_csverror_bad_lines选项来跳过这些行。

import pandas as pd


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

这是有效的,因为“糟糕的台词”;在pandas中定义的,包括其中一个字段超过CSV限制的行。

注意,此解决方案仅在csv文件不应该中的字段如此长时有效。 如果你期望有大的字段大小,这将丢弃你的数据