Pandas read_csv ожидает неправильное количество столбцов, с оборванным файлом csv
У меня есть файл csv, который содержит несколько сотен строк и 26 столбцов, но последние несколько столбцов имеют только значение в нескольких строках, и они находятся к середине или концу файла. Когда я пытаюсь прочитать его при использовании read_csv(), я получаю следующую ошибку.
"ValueError: ожидая 23 столбца, получив 26 в строке 64"
Я не вижу, где явно указывать количество столбцов в файле или как он определяет, сколько столбцов он считает файлом.
Дамп ниже
In [3]:
infile =open(easygui.fileopenbox(),"r")
pledge = read_csv(infile,parse_dates='true')
---------------------------------------------------------------------------
ValueError Traceback (most recent call last)
<ipython-input-3-b35e7a16b389> in <module>()
1 infile =open(easygui.fileopenbox(),"r")
2
----> 3 pledge = read_csv(infile,parse_dates='true')
C:\Python27\lib\site-packages\pandas-0.8.1-py2.7-win32.egg\pandas\io\parsers.pyc in read_csv(filepath_or_buffer, sep, dialect, header, index_col, names, skiprows, na_values, thousands, comment, parse_dates, keep_date_col, dayfirst, date_parser, nrows, iterator, chunksize, skip_footer, converters, verbose, delimiter, encoding, squeeze)
234 kwds['delimiter'] = sep
235
--> 236 return _read(TextParser, filepath_or_buffer, kwds)
237
238 @Appender(_read_table_doc)
C:\Python27\lib\site-packages\pandas-0.8.1-py2.7-win32.egg\pandas\io\parsers.pyc in _read(cls, filepath_or_buffer, kwds)
189 return parser
190
--> 191 return parser.get_chunk()
192
193 @Appender(_read_csv_doc)
C:\Python27\lib\site-packages\pandas-0.8.1-py2.7-win32.egg\pandas\io\parsers.pyc in get_chunk(self, rows)
779 msg = ('Expecting %d columns, got %d in row %d' %
780 (col_len, zip_len, row_num))
--> 781 raise ValueError(msg)
782
783 data = dict((k, v) for k, v in izip(self.columns, zipped_content))
ValueError: Expecting 23 columns, got 26 in row 64
Ответы
Ответ 1
Вы можете использовать параметр names
. Например, если у вас есть файл csv:
1,2,1
2,3,4,2,3
1,2,3,3
1,2,3,4,5,6
И попробуйте прочитать его, вы получите сообщение об ошибке
>>> pd.read_csv(r'D:/Temp/tt.csv')
Traceback (most recent call last):
...
Expected 5 fields in line 4, saw 6
Но если вы передадите параметры names
, вы получите результат:
>>> pd.read_csv(r'D:/Temp/tt.csv', names=list('abcdef'))
a b c d e f
0 1 2 1 NaN NaN NaN
1 2 3 4 2 3 NaN
2 1 2 3 3 NaN NaN
3 1 2 3 4 5 6
Надеюсь, что это поможет.
Ответ 2
вы также можете загрузить CSV с разделителем "^", чтобы загрузить всю строку в столбец, а затем использовать split, чтобы разбить строку на требуемые разделители. После этого вы выполняете concat для слияния с исходным фреймворком данных (при необходимости).
temp=pd.read_csv('test.csv',sep='^',header=None,prefix='X')
temp2=temp.X0.str.split(',',expand=True)
del temp['X0']
temp=pd.concat([temp,temp2],axis=1)
Ответ 3
Предположим, что у вас есть такой файл:
a,b,c
1,2,3
1,2,3,4
Вы можете использовать csv.reader
, чтобы сначала очистить файл,
lines=list(csv.reader(open('file.csv')))
header, values = lines[0], lines[1:]
data = {h:v for h,v in zip (header, zip(*values))}
и получим:
{'a' : ('1','1'), 'b': ('2','2'), 'c': ('3', '3')}
Если у вас нет заголовка, вы можете использовать:
data = {h:v for h,v in zip (str(xrange(number_of_columns)), zip(*values))}
а затем вы можете преобразовать словарь в dataframe с помощью
import pandas as pd
df = pd.DataFrame.from_dict(data)
Ответ 4
Проблема с данным решением заключается в том, что вам нужно знать максимальное количество требуемых столбцов. Я не мог найти прямую функцию для этой проблемы, но вы можете, безусловно, написать def, который может:
- прочитайте все строки
- разделить его
- подсчитать количество слов/элементов в каждой строке
- сохранить максимальное количество слов/элементов
- укажите максимальное значение в опции имен (как предложено Roman Pekar)
Вот def (function), который я написал для своих файлов:
def ragged_csv(filename):
f=open(filename)
max_n=0
for line in f.readlines():
words = len(line.split(' '))
if words > max_n:
max_n=words
lines=pd.read_csv(filename,sep=' ',names=range(max_n))
return lines