起因

今天又是编写代码的一天,在使用pandasread_csv读取文件时候,程序运行突然出现了错误

  1. Traceback (most recent call last):
  2. File "<stdin>", line 1, in <module>
  3. File "C:\software\Anaconda3\lib\site-packages\pandas\io\parsers.py", line 610, in read_csv
  4. return _read(filepath_or_buffer, kwds)
  5. File "C:\software\Anaconda3\lib\site-packages\pandas\io\parsers.py", line 468, in _read
  6. return parser.read(nrows)
  7. File "C:\software\Anaconda3\lib\site-packages\pandas\io\parsers.py", line 1057, in read
  8. index, columns, col_dict = self._engine.read(nrows)
  9. File "C:\software\Anaconda3\lib\site-packages\pandas\io\parsers.py", line 2061, in read
  10. data = self._reader.read(nrows)
  11. File "pandas\_libs\parsers.pyx", line 756, in pandas._libs.parsers.TextReader.read
  12. File "pandas\_libs\parsers.pyx", line 771, in pandas._libs.parsers.TextReader._read_low_memory
  13. File "pandas\_libs\parsers.pyx", line 827, in pandas._libs.parsers.TextReader._read_rows
  14. File "pandas\_libs\parsers.pyx", line 814, in pandas._libs.parsers.TextReader._tokenize_rows
  15. File "pandas\_libs\parsers.pyx", line 1951, in pandas._libs.parsers.raise_parser_error
  16. pandas.errors.ParserError: Error tokenizing data. C error: Expected 6 fields in line 3, saw 9

pandas.errors.ParserError: Error tokenizing data. C error: Expected 6 fields in line 3, saw 9

读取的数据test.csv类似是这样:

  1. 23,123,323
  2. 3213,323,5454,6768,8788,54
  3. 3434,3456,6768,898,90,675,5435,24324,24324

查阅博客

很多博主的解决方法就是在read_csv函数中加参数error_bad_lines=False

参数的error_bad_lines=False的含义通过查阅官方文档(官方文档yyds!)

pandas.read_csv — pandas 1.3.5 documentation (pydata.org)

我们可以发现:

error_bad_lines bool, default None

Lines with too many fields (e.g. a csv line with too many commas) will by default cause an exception to be raised, and no DataFrame will be returned. If False, then these “bad lines” will be dropped from the DataFrame that is returned.

包含太多字段的行(例如,包含太多逗号的 csv 行)默认会引发异常,并且不会返回任何 DataFrame。 如果为 False,那么这些坏行将从返回的 DataFrame中删除。

Deprecated since version 1.3.0: The parameter should be used instead to specify behavior upon encountering a bad line instead.on_bad_lines

自 1.3.0 版起已弃用: 应改用on_bad_lines定义参数来指定遇到坏行时的行为。

pandas使用read_csv读取时,将第一行视为表头。当第二行的数据列数大于表头列数时候,就会报错。此时如果使用error_bad_lines=False,数据列数大于表头列数的那一行就会被视为坏行而被抛弃,不会显示在read_csv读取的数据中。但是这种处理方式不满足我的要求。我想把所有的数据都存起来,而不是抛弃那些过长的行。

  1. >>> a = pd.read_csv('test.csv',error_bad_lines=False)
  2. b'Skipping line 3: expected 6 fields, saw 9\n'
  3. >>> print(a)
  4. 23 123 323
  5. 3213 323 5454 6768 8788 54

查阅官方文档

那怎么办呢?

这时候还是要查阅官方文档

既然,表头不满足pandas读取数据的要求,那我自己设定一个列数远大于数据中最长的那列的表头不就行了?

例如上面数据中最长的一行有3434,3456,6768,898,90,675,5435,24324,24324 9个数据,那么我设定一个数量大于等于9的表头不就可以了?

这时候需要的参数就是:

names array-like, optional

List of column names to use. If the file contains a header row, then you should explicitly pass to override the column names. Duplicates in this list are not allowed.header=0

要使用的列名称列表。 如果文件包含标题行,那么您应该显式传递以覆盖列名称。 不允许在此列表中重复使用header=0

names参数就可以自定义表头名字,这样这个问题就可以完美解决了。

我们直接定义表头为1,2,3,4,5,6,7,8,9, 再去读文件看看:

  1. >>> a = pd.read_csv('test.csv',names =['1','2','3','4','5','6','7','8','9'])
  2. >>> print(a)
  3. 1 2 3 4 5 6 7 8 9
  4. 0 23 123 323 NaN NaN NaN NaN NaN NaN
  5. 1 3213 323 5454 6768.0 8788.0 54.0 NaN NaN NaN
  6. 2 3434 3456 6768 898.0 90.0 675.0 5435.0 24324.0 24324.0