我有一个脚本在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文件?跳过具有大字段的行是不可取的,因为数据需要在后续步骤中进行分析。


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 (SO: what-is-sys-maxint-in-python-3)

更新

正如Geoff指出的那样,上面的代码可能会导致以下错误:OverflowError: Python int太大,无法转换为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]来控制。: csv.field_size_limit([new_limit])(重点是我的):

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

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

>>>导入CSV >>> >>> >>> limit0 = csv.field_size_limit() > > > limit0 131072 > > >“0 x {0:016X}”.format (limit0) “0 x0000000000020000”

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

在幕后(查看[GitHub]: python/cpython - (master) cpython/Modules/_csv.c了解实现细节),保存该值的变量是一个C long ([Wikipedia]: C data types),其大小取决于CPU架构和操作系统(ILP)。经典的区别:对于064位操作系统(和Python版本),长类型大小(以位为单位)是:

拒绝:64 胜利:32

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

>>>导入sys, ctypes as ct >>> >>> > > >“v {: d}, {: d}。{:d}”.format (* sys.version_info[3]),系统。平台,系统。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) 回溯(最近一次调用): 文件“<stdin>”,第1行,在<模块> Python int太大,不能转换为C long

为了避免遇到这个问题,可以使用一种技巧(感谢[Python. max])设置(最大可能的)限制(LONG_MAX)。ctypes - Python的外部函数库)。它应该在任何CPU / OS上的Python 3和Python 2上工作。

> > > csv.field_size_limit (int (ct.c_ulong(1)。值// 2)) 131072 >>> limit1 = csv.field_size_limit() > > > limit1 2147483647 > > >“0 x {0:016X}”.format (limit1) “0 x000000007fffffff”

064bit Python在类似Nix的操作系统上:

>>>导入sys, csv, ctypes作为ct >>> >>> > > >“v {: d}, {: d}。{:d}”.format (* sys.version_info[3]),系统。平台,系统。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)。值// 2)) 131072 >>> limit1 = csv.field_size_limit() > > > limit1 9223372036854775807 > > >“0 x {0:016X}”.format (limit1) “0 x7fffffffffffffff”

对于032位的Python,不需要这个技巧(因为sys。maxsize和LONG_MAX宽度为032位)。如果这个最大值仍然不够,那么.csv将需要手动干预才能从Python中处理。

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

[SO]: Python中C类型整数的最大值和最小值(@CristiFati的答案) Python 064bit vs 032bit差异:[SO]:如何确定我的Python shell在OS X上以32位还是64位模式执行?(@CristiFati回答)

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

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

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

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

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

您可以使用pd的error_bad_lines选项。Read_csv来跳过这些行。

import pandas as pd

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

这是有效的,因为在pandas中定义的“坏行”包括其中一个字段超过csv限制的行。

注意,这个解决方案只在csv文件中的字段不应该这么长时才有效。 如果您希望有大的字段大小,这将丢弃您的数据。