Python Pandas错误标记数据

时间:2013-08-04 01:54:45

标签: python csv pandas

我试图使用pandas来操作.csv文件,但是我收到了这个错误:

  

pandas.parser.CParserError:标记数据时出错。 C错误:第3行预计有2个字段,见12

我曾尝试阅读pandas docs,但一无所获。

我的代码很简单:

path = 'GOOG Key Ratios.csv'
#print(open(path).read())
data = pd.read_csv(path)

我该如何解决这个问题?我应该使用csv模块还是其他语言?

档案来自Morningstar

40 个答案:

答案 0 :(得分:351)

你也可以试试;

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

请注意,这会导致跳过违规行。

答案 1 :(得分:62)

这可能是

的问题
  • 数据中的分隔符
  • 第一行,如@TomAugspurger所说

要解决此问题,请在调用sep时尝试指定header和/或read_csv个参数。例如,

df = pandas.read_csv(fileName, sep='delimiter', header=None)

在上面的代码中,sep定义了分隔符,header=None告诉pandas您的源数据没有标题/列标题行。因此,the docs:"如果文件不包含标题行,则应明确传递header = None"。在这种情况下,pandas会自动为每个字段{0,1,2,...}创建整数索引。

根据文档,分隔符应该是一个问题。文档说"如果sep是None [未指定],将尝试自动确定这个。"然而,我对此并没有好运,包括具有明显分隔符的实例。

答案 2 :(得分:32)

解析器对文件的标题感到困惑。它读取第一行并推断该行的列数。但前两行并不代表文件中的实际数据。

使用data = pd.read_csv(path, skiprows=2)

尝试

答案 3 :(得分:26)

您的CSV文件可能包含可变数量的列,read_csv推断出前几行中的列数。在这种情况下,有两种解决方法:

1)将CSV文件更改为具有最大列数的虚拟第一行(并指定header=[0]

2)或使用names = list(range(0,N)),其中N是最大列数。

答案 4 :(得分:15)

这绝对是分隔符的问题,因为大多数csv CSV都是使用sep='/t'创建的,因此请使用分隔符read_csv使用制表符(\t)尝试/t 。所以,尝试使用以下代码行打开。

data=pd.read_csv("File_path", sep='\t')

答案 5 :(得分:15)

我也有这个问题,但也许是出于其他原因。我的CSV中有一些尾随逗号,它们添加了一个pandas试图阅读的附加列。使用以下工作,但它只是忽略了不好的行:

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

如果你想保持线条是一种丑陋的黑客来处理错误,那就是做如下事情:

line     = []
expected = []
saw      = []     
cont     = True 

while cont == True:     
    try:
        data = pd.read_csv('file1.csv',skiprows=line)
        cont = False
    except Exception as e:    
        errortype = e.message.split('.')[0].strip()                                
        if errortype == 'Error tokenizing data':                        
           cerror      = e.message.split(':')[1].strip().replace(',','')
           nums        = [n for n in cerror.split(' ') if str.isdigit(n)]
           expected.append(int(nums[0]))
           saw.append(int(nums[2]))
           line.append(int(nums[1])-1)
         else:
           cerror      = 'Unknown'
           print 'Unknown Error - 222'

if line != []:
    # Handle the errors however you want

我继续编写一个脚本,将这些行重新插入到DataFrame中,因为坏行将由变量' line'在上面的代码中。只需使用csv阅读器就可以避免这一切。希望大熊猫开发人员能够在将来更轻松地处理这种情况。

答案 6 :(得分:9)

我自己曾经有过几次这个问题。几乎每次,原因是我试图打开的文件不是一个正确保存的CSV开始。通过"正确",我的意思是每行具有相同数量的分隔符或列。

通常情况发生是因为我在Excel中打开了CSV然后不正确地保存了它。即使文件扩展名仍为.csv,纯CSV格式也已更改。

使用pandas to_csv保存的任何文件都将正确格式化,并且不应该出现此问题。但是如果你用另一个程序打开它,它可能会改变结构。

希望有所帮助。

答案 7 :(得分:7)

我遇到了同样的问题。在同一源文件上使用pd.read_table()似乎有效。我无法追查其原因,但这对我的案例来说是一个有用的解决方法。或许知识渊博的人可以更清楚地了解其工作原理。

编辑: 当您在文件中有一些文本与实际数据格式不同时,我发现此错误会逐渐增加。这通常是页眉或页脚信息(大于一行,因此skip_header不起作用),它们不会被与实际数据相同数量的逗号分隔(使用read_csv时)。使用read_table使用选项卡作为分隔符,可以绕过用户当前的错误但引入其他错误。

我通常通过将额外数据读入文件然后使用read_csv()方法来解决这个问题。

确切的解决方案可能因您的实际文件而异,但在某些情况下这种方法对我有用

答案 8 :(得分:5)

在尝试使用空格,逗号和引号读取制表符分隔的表时,我遇到了类似的问题:

1115794 4218    "k__Bacteria", "p__Firmicutes", "c__Bacilli", "o__Bacillales", "f__Bacillaceae", ""
1144102 3180    "k__Bacteria", "p__Firmicutes", "c__Bacilli", "o__Bacillales", "f__Bacillaceae", "g__Bacillus", ""
368444  2328    "k__Bacteria", "p__Bacteroidetes", "c__Bacteroidia", "o__Bacteroidales", "f__Bacteroidaceae", "g__Bacteroides", ""



import pandas as pd
# Same error for read_table
counts = pd.read_csv(path_counts, sep='\t', index_col=2, header=None, engine = 'c')

pandas.io.common.CParserError: Error tokenizing data. C error: out of memory

这说明它与C解析引擎(默认情况下)有关。也许更改为python会更改任何内容

counts = pd.read_table(path_counts, sep='\t', index_col=2, header=None, engine='python')

Segmentation fault (core dumped)

现在这是一个不同的错误 如果我们继续尝试从表中删除空格,python-engine的错误将再次发生变化:

1115794 4218    "k__Bacteria","p__Firmicutes","c__Bacilli","o__Bacillales","f__Bacillaceae",""
1144102 3180    "k__Bacteria","p__Firmicutes","c__Bacilli","o__Bacillales","f__Bacillaceae","g__Bacillus",""
368444  2328    "k__Bacteria","p__Bacteroidetes","c__Bacteroidia","o__Bacteroidales","f__Bacteroidaceae","g__Bacteroides",""


_csv.Error: '   ' expected after '"'

很明显,大熊猫在解析我们的行时遇到了问题。要使用python引擎解析表,我需要事先从表中删除所有空格和引号。与此同时,C引擎即使用逗号连续排列也一直在崩溃。

为了避免使用替换创建新文件,我这样做,因为我的表很小:

from io import StringIO
with open(path_counts) as f:
    input = StringIO(f.read().replace('", ""', '').replace('"', '').replace(', ', ',').replace('\0',''))
    counts = pd.read_table(input, sep='\t', index_col=2, header=None, engine='python')

<强> TL;博士
更改解析引擎,尽量避免数据中的任何非分隔引号/逗号/空格。

答案 9 :(得分:4)

我遇到了这个问题,我试图在不传递列名的情况下以CSV格式进行读取。

df = pd.read_csv(filename, header=None)

我预先在列表中指定了列名,然后将它们传递到names中,它立即解决了。如果您没有设置列名,则可以创建与数据中可能存在的最大列数一样多的占位符名称。

col_names = ["col1", "col2", "col3", ...]
df = pd.read_csv(filename, names=col_names)

答案 10 :(得分:3)

虽然不是这个问题的情况,但压缩数据也可能出现此错误。明确设置kwarg compression的值可以解决我的问题。

result = pandas.read_csv(data_source, compression='gzip')

答案 11 :(得分:3)

您可以尝试;

data = pd.read_csv('file1.csv', sep='\t')

答案 12 :(得分:3)

以下内容对我有用(我发布了此答案,因为我特别在Google合作笔记本中遇到了此问题):

df = pd.read_csv("/path/foo.csv", delimiter=';', skiprows=0, low_memory=False)

答案 13 :(得分:3)

以下命令序列工作(我丢失了数据的第一行-no header = None present-,但至少它加载了):

df = pd.read_csv(filename, usecols=range(0, 42)) df.columns = ['YR', 'MO', 'DAY', 'HR', 'MIN', 'SEC', 'HUND', 'ERROR', 'RECTYPE', 'LANE', 'SPEED', 'CLASS', 'LENGTH', 'GVW', 'ESAL', 'W1', 'S1', 'W2', 'S2', 'W3', 'S3', 'W4', 'S4', 'W5', 'S5', 'W6', 'S6', 'W7', 'S7', 'W8', 'S8', 'W9', 'S9', 'W10', 'S10', 'W11', 'S11', 'W12', 'S12', 'W13', 'S13', 'W14']

以下不起作用:

df = pd.read_csv(filename, names=['YR', 'MO', 'DAY', 'HR', 'MIN', 'SEC', 'HUND', 'ERROR', 'RECTYPE', 'LANE', 'SPEED', 'CLASS', 'LENGTH', 'GVW', 'ESAL', 'W1', 'S1', 'W2', 'S2', 'W3', 'S3', 'W4', 'S4', 'W5', 'S5', 'W6', 'S6', 'W7', 'S7', 'W8', 'S8', 'W9', 'S9', 'W10', 'S10', 'W11', 'S11', 'W12', 'S12', 'W13', 'S13', 'W14'], usecols=range(0, 42))

CParserError:标记数据时出错。 C错误:预计行1605634中的53个字段,见54 以下不起作用:

df = pd.read_csv(filename, header=None)

CParserError:标记数据时出错。 C错误:预计行1605634中的53个字段,见54

因此,在您的问题中,您必须通过usecols=range(0, 2)

答案 14 :(得分:3)

在我的情况下,分隔符不是默认的“,”,而是Tab键。

pd.read_csv(file_name.csv, sep='\\t',lineterminator='\\r', engine='python', header='infer')

注意:“ \ t”不符合某些消息来源的建议。 “ \\ t”为必填项。

答案 15 :(得分:2)

使用 pandas.read_csv('CSVFILENAME',header=None,sep=', ')

尝试从链接中读取csv数据时

http://archive.ics.uci.edu/ml/machine-learning-databases/adult/adult.data

我将网站上的数据复制到我的csvfile中。它有额外的空格,所以使用sep =','并且它起作用了:)

答案 16 :(得分:2)

对于那些在Linux OS上使用Python 3遇到类似问题的人。

pandas.errors.ParserError: Error tokenizing data. C error: Calling
read(nbytes) on source failed. Try engine='python'.

尝试:

df.read_csv('file.csv', encoding='utf8', engine='python')

答案 17 :(得分:2)

在参数中使用定界符

pd.read_csv(filename, delimiter=",", encoding='utf-8')

它将读取。

答案 18 :(得分:2)

这就是我所做的。

sep='::'解决了我的问题:

data=pd.read_csv('C:\\Users\\HP\\Downloads\\NPL ASSINGMENT 2 imdb_labelled\\imdb_labelled.txt',engine='python',header=None,sep='::')

答案 19 :(得分:2)

我发现在处理类似的解析错误时有用的替代方法是使用CSV模块将数据重新路由到pandas df中。例如:

import csv
import pandas as pd
path = 'C:/FileLocation/'
file = 'filename.csv'
f = open(path+file,'rt')
reader = csv.reader(f)

#once contents are available, I then put them in a list
csv_list = []
for l in reader:
    csv_list.append(l)
f.close()
#now pandas has no problem getting into a df
df = pd.DataFrame(csv_list)

我发现CSV模块对于格式不佳的逗号分隔文件来说更加健壮,所以这条路线成功解决了这些问题。

答案 20 :(得分:2)

有时候问题不是如何使用python,而是使用原始数据 我收到此错误消息

 doc = new Document();
    DocumentBuilder builder = new DocumentBuilder(doc);
    Stream memStream = File.OpenRead("addreess+file.xls");
    Shape oleObject = builder.InsertOleObject(memStream, "AcroExch.Document.7"", false, null);

原来,在列描述中有时候会有逗号。这意味着需要清理CSV文件或使用其他分隔符。

答案 21 :(得分:1)

标记数据时出错。 C错误:第3行中应该有2个字段,看到的是12

该错误为解决以下问题提供了线索:“第3行中预期有2个字段,锯12”,锯12表示第二行的长度为12,第一行的长度为2。

当您拥有如下所示的数据时,如果您跳过行,那么大多数数据将被跳过

data = """1,2,3
1,2,3,4
1,2,3,4,5
1,2
1,2,3,4"""

如果您不想跳过任何行,请执行以下操作

#First lets find the maximum column for all the rows
with open("file_name.csv", 'r') as temp_f:
    # get No of columns in each line
    col_count = [ len(l.split(",")) for l in temp_f.readlines() ]

### Generate column names  (names will be 0, 1, 2, ..., maximum columns - 1)
column_names = [i for i in range(max(col_count))] 

import pandas as pd
# inside range set the maximum value you can see in "Expected 4 fields in line 2, saw 8"
# here will be 8 
data = pd.read_csv("file_name.csv",header = None,names=column_names )

使用范围而不是手动设置名称,因为当您有很多列时,这会很麻烦。

此外,如果需要使用偶数数据长度,则可以用0填充NaN值。例如。用于聚类(k均值)

new_data = data.fillna(0)

答案 22 :(得分:1)

就我而言,这是因为csv文件的第一行和最后两行的格式与文件的中间内容不同。

所以我要做的是将csv文件作为字符串打开,解析字符串的内容,然后使用read_csv获取数据框。

import io
import pandas as pd

file = open(f'{file_path}/{file_name}', 'r')
content = file.read()

# change new line character from '\r\n' to '\n'
lines = content.replace('\r', '').split('\n')

# Remove the first and last 2 lines of the file
# StringIO can be considered as a file stored in memory
df = pd.read_csv(StringIO("\n".join(lines[2:-2])), header=None)

答案 23 :(得分:1)

据我所知,在看完文件后,问题在于您要加载的csv文件具有多个表。有空行或包含表标题的行。尝试看看这个Stackoverflow answer。它显示了如何以编程方式实现这一目标。

另一种实现此目的的动态方法是使用csv module,一次读取每一行并进行完整性检查/正则表达式,以推断该行是否为(标题/标题/值/空白) 。这种方法还有一个优势,那就是您可以根据需要在python对象中拆分/追加/收集数据。

最简单的方法是在手动选择表格并将其复制到剪贴板后使用pandas函数pd.read_clipboard(),以防您可以在excel中打开CSV或其他功能。

引诱剂

此外,与您的问题无关,但因为没有人提到此问题:从UCI加载某些数据集(例如seeds_dataset.txt)时,我遇到了同样的问题。在我的情况下,发生此错误是因为某些分隔符比真正的制表符\t具有更多的空格。例如,请参见下面的第3行

14.38   14.21   0.8951  5.386   3.312   2.462   4.956   1
14.69   14.49   0.8799  5.563   3.259   3.586   5.219   1
14.11   14.1    0.8911  5.42    3.302   2.7     5       1

因此,请在分隔符模式中使用\t+而不是\t

data = pd.read_csv(path, sep='\t+`, header=None)

答案 24 :(得分:1)

有时在一个单元格中有一个逗号“,”。由于熊猫无法阅读它。 尝试使用“;”分隔符

df = pd.read_csv(r'yourpath', delimiter=";")

答案 25 :(得分:1)

我相信解决方案

,engine='python'
, error_bad_lines = False
如果

是虚拟列并且您要删除它,那将是很好的选择。 在我的情况下,第二行实际上有更多的列,我希望将这些列集成在一起,并使列数= MAX(columns)。

请参考以下我无法在任何地方阅读的解决方案:

try:
    df_data = pd.read_csv(PATH, header = bl_header, sep = str_sep)
except pd.errors.ParserError as err:
    str_find = 'saw '
    int_position = int(str(err).find(str_find)) + len(str_find)
    str_nbCol = str(err)[int_position:]
    l_col = range(int(str_nbCol))
    df_data = pd.read_csv(PATH, header = bl_header, sep = str_sep, names = l_col)

答案 26 :(得分:1)

简单分辨率:在excel中打开csv文件,然后将其保存为csv格式的其他名称文件。再次尝试导入spyder,将解决您的问题!

答案 27 :(得分:1)

我使用的数据集使用了很多引号(“)来进行格式设置。我能够通过为read_csv()包含此参数来修复错误:

quoting=3 # 3 correlates to csv.QUOTE_NONE for pandas

答案 28 :(得分:1)

当read_csv时,我有同样的问题:ParserError:标记数据时出错。 我只是将旧的csv文件保存到新的csv文件中。问题解决了!

答案 29 :(得分:1)

我的情况与此类似,并且设置

train = pd.read_csv('input.csv' , encoding='latin1',engine='python') 

工作

答案 30 :(得分:1)

我有一个包含现有行号的数据集,我使用了index_col:

pd.read_csv('train.csv', index_col=0)

答案 31 :(得分:0)

已经提到了大多数有用的答案,但是我建议将熊猫数据帧另存为实木复合地板文件。实木复合地板文件没有此问题,并且它们同时具有存储效率。

答案 32 :(得分:0)

我遇到了带有引号的错误。我使用映射软件,在导出逗号分隔文件时,该软件会在文本项周围加上引号。使用引号(例如'=英尺和“ =英寸)的文本可能会引起问题。请考虑以下示例,该示例指出5英寸的测井记录质量较差:

UWI_key,Latitude,Longitude,Remark US42051316890000,30.4386484,-96.4330734,"poor 5""

使用5"作为5 inch的简写形式最终会在工作中投入一把扳手。 Excel会简单地删除多余的引号,但是Pandas会在没有上述error_bad_lines=False参数的情况下崩溃。

一旦您知道错误的性质,最简单的方法是在导入之前通过文本编辑器(例如Sublime Text 3或Notepad ++)进行查找替换。

答案 33 :(得分:0)

我遇到了带有引号的错误。我使用映射软件,在导出逗号分隔文件时,该软件会在文本项周围加上引号。使用引号(例如'=英尺和“ =英寸)的文本可能会引起问题。请考虑以下示例,该示例指出5英寸的测井记录质量较差:

const tabledata1 = [{ id: "1", name: "Oli Bob", location: "United Kingdom", gender: "male", col: "red", dob: "14/04/1984", _children: [{ id: "2", name: "Mary May", location: "Germany", gender: "female", col: "blue", dob: "14/05/1982" }, { name: "Christine Lobowski", location: "France", gender: "female", col: "green", dob: "22/05/1982" }, { name: "Brendon Philips", location: "USA", gender: "male", col: "orange", dob: "01/08/1980", _children: [{ name: "Margret Marmajuke", location: "Canada", gender: "female", col: "yellow", dob: "31/01/1999" }, { name: "Frank Harbours", location: "Russia", gender: "male", col: "red", dob: "12/05/1966" }, ] }, ] }, { name: "Jamie Newhart", location: "India", gender: "male", col: "green", dob: "14/05/1985" }, { name: "Gemma Jane", location: "China", gender: "female", col: "red", dob: "22/05/1982", _children: [{ name: "Emily Sykes", location: "South Korea", gender: "female", col: "maroon", dob: "11/11/1970" }, ] }, { name: "James Newman", location: "Japan", gender: "male", col: "red", dob: "22/03/1998" }, ]; const table = new Tabulator("#example-table", { height: 205, // set height of table (in CSS or here), this enables the Virtual DOM and improves render speed dramatically (can be any valid css height value) data: tabledata1, //assign data to table selectable: true, //make rows selectable layout: "fitColumns", //fit columns to width of table (optional) autoColumns: true, dataTree: true, dataTreeStartExpanded: true, renderComplete: function() { console.log('done'); this.selectRow(2); } });

使用UWI_key,Latitude,Longitude,Remark US42051316890000,30.4386484,-96.4330734,"poor 5""作为5"的简写形式最终会在工作中投入一把扳手。 Excel会简单地删除多余的引号,但是Pandas会在没有上述5 inch参数的情况下崩溃。

答案 34 :(得分:0)

对我来说,问题是在我的CSV 日内中添加了新列。如果我使用error_bad_lines=False,则接受的答案解决方案将无法工作,因为每个将来的行都将被丢弃。

在这种情况下,解决方案是在pd.read_csv()中使用usecols参数。这样,我可以只指定需要读入CSV的列,并且只要标头列存在(并且列名不变),我的Python代码就可以对将来的CSV更改保持弹性。

usecols : list-like or callable, optional 

Return a subset of the columns. If list-like, all elements must either
be positional (i.e. integer indices into the document columns) or
strings that correspond to column names provided either by the user in
names or inferred from the document header row(s). For example, a
valid list-like usecols parameter would be [0, 1, 2] or ['foo', 'bar',
'baz']. Element order is ignored, so usecols=[0, 1] is the same as [1,
0]. To instantiate a DataFrame from data with element order preserved
use pd.read_csv(data, usecols=['foo', 'bar'])[['foo', 'bar']] for
columns in ['foo', 'bar'] order or pd.read_csv(data, usecols=['foo',
'bar'])[['bar', 'foo']] for ['bar', 'foo'] order.

示例

my_columns = ['foo', 'bar', 'bob']
df = pd.read_csv(file_path, usecols=my_columns)

这的另一个好处是,如果我只使用3-4列的CSV(具有18-20列),则可以将较少的数据加载到内存中。

答案 35 :(得分:0)

问题可能与文件问题有关,就我而言,问题是在重命名文件后解决的。尚未找出原因。

答案 36 :(得分:0)

您可以执行此步骤以避免出现问题-

train = pd.read_csv('/home/Project/output.csv' , header=None)

只需添加-header=None

希望这会有所帮助!

答案 37 :(得分:0)

我遇到了类似的错误,问题是我的csv文件中有一些转义引号,需要适当设置escapechar参数。

答案 38 :(得分:-1)

我从同事那里收到了一个.csv,当我尝试使用pd.read_csv()读取csv时,我收到了类似的错误。显然,它试图使用第一行为数据帧生成列,但是有许多行包含的列比第一行所暗示的要多。我最终通过简单地打开文件并将其另存为.csv并再次使用pd.read_csv()来解决了这个问题。

答案 39 :(得分:-2)

尝试:removeAttribute()