Разделение файлов csv с несогласованными номерами столбцов

#python #python-3.x #pandas

#python #python-3.x #pandas

Вопрос:

У меня есть файл CSV, который отформатирован, как показано ниже, за исключением того, что в нем около 20 миллионов строк:

 A,B,C,D
1,2,3,4
1,1,3,4
1,0,0,1,4,3
1,0,5,6,2,1
  

Который я пытаюсь прочитать с помощью pandas следующим образом:

 df = pd.read_csv(_out_path, sep=',', engine='c') # engine c because it's faster
  

Что вызывает следующую ошибку:

 ParserError: Error tokenizing data. C error: Expected 18 fields in line 13674206, saw 31
  

С помощью приведенного выше тестового файла pandas обрабатывает это и добавляет два неназванных столбца, которые содержат np.NAN для первых двух строк.

 A   B   C   D   Unnamed: 4  Unnamed: 5
0   1   2   3   4   NaN NaN
1   1   1   3   4   NaN NaN
2   1   0   0   1   4.0 3.0
3   1   0   5   6   2.0 1.0
  

Однако для реального файла (которым я, к сожалению, не могу поделиться) это вызывает указанную выше ошибку.

Я ищу способ обойти это, найдя строку с наибольшим количеством запятых, посчитайте количество запятых и добавьте столько запятых, сколько нужно, в каждую строку, чтобы pandas прочитал файл. Или в идеале для более простого способа чтения файла в любом случае.


Редактировать:

Данные были объединены из нескольких сотен файлов CSV, но в середине были добавлены новые столбцы (к сожалению, не все в конце). Таким образом, хорошим решением (спасибо за комментарии) было бы разделить файл, в котором изменяется количество записей.

Кроме того, в файле нет заголовков. Я попытался добавить их вручную в первую строку для этого примера, поэтому, думаю, мне придется добавить заголовки после разделения файла.

Комментарии:

1. Если вам не нужны дополнительные столбцы, вы можете попробовать usecols=[0,1,2,3] . Кроме того, вы можете пропустить и записать неверные строки с error_bad_lines=False warn_bad_lines=True помощью . pandas.pydata.org/pandas-docs/stable/user_guide/io.html

2. По-видимому, это слияние нескольких сотен csv. В какой-то момент они начали добавлять больше столбцов данных… к сожалению, он был добавлен где-то посередине, и теперь нужные мне данные сместились. Моя идея состояла в том, чтобы разделить фрейм данных с использованием условия, при котором дополнительный столбец является na или нет, а затем переставить столбцы. В качестве альтернативы я мог бы разделить файл CSV в соответствии с количеством запятых в строке, но я не знаю, как это сделать

3. Это ужасно. Тот, кто решил, что эти данные должны быть объединены, заслуживает наказания. Если вы готовы сформулировать вопрос так, чтобы он запрашивал разделение данных, я был бы готов написать ответ. Было бы хорошо знать, есть ли новые заголовки в строках, где увеличивается количество столбцов, или это только цифры после первой строки.

4. Я отредактировал вопрос, чтобы добавить разделение

Ответ №1:

Чтобы иметь чистые наборы данных, лучше всего разделить их на отдельные файлы.

Если количество столбцов только увеличивается и никогда не уменьшается, вы можете легко отслеживать разные файлы назначения с помощью словаря:

 source_file = open('mixed_data.csv', 'r')

destination_files = {}

for line in source_file:
    item_count = len(line.split(','))

    try:
        dest_file = destination_files[item_count]

    except KeyError:
        file_name = 'split_data_'   str(item_count)   '.csv'
        dest_file = destination_files[item_count] = open(file_name, 'w')

    dest_file.write(line)

for dest_file in destination_files.values():
    dest_file.close()

source_file.close()
  

Закрытие не является строго необходимым, если программа завершается сразу после этого или область, в которой привязаны файловые объекты, оставлена, но в любом случае это хорошая практика.

Комментарии:

1. Я подозреваю, что это может занять некоторое время с десятками миллионов строк. Существуют необязательные аргументы, в open() которых можно настроить различные виды буферизации (если версия Python не слишком старая), которые могут или не могут немного ускорить его.