У меня есть файл CSV, в котором я использую Python для анализа. Я обнаружил, что некоторые строки в файле имеют разное количество столбцов.
001;Snow,Jon;19801201
002;Crom,Jake;19920103
003; ;Wise,Frank;19880303 <-- Invalid row
004;Wiseau,Tommy;4324;1323;2323 <-- Invalid row
Я хотел бы записать эти недопустимые строки в отдельный текстовый файл.
Я использовал эту строку кода для чтения из файла.
df = pd.read_csv('names.csv', header=None,sep=';')
Одно решение, которое я нашел здесь, заключалось в том, чтобы пропустить проблемные строки, используя следующий код:
data = pd.read_csv('file1.csv', on_bad_lines='skip')
Я мог бы изменить «пропустить» на «предупредить», что даст номер проблемной строки и пропустит строку. Но это вернет предупреждающие сообщения, а не саму строку.






Вы можете разделить файл csv с помощью скрипта, который вы запускаете перед загрузкой в Pandas. Такой как;
with open('names.csv') as src, open('good.csv', 'w') as good, open('bad.csv', 'w') as bad:
for line in src:
if line.count(';') == 2: # or any other appropriate criteria
good.write(line)
else:
bad.write(line)
Поскольку pandas 1.4.0 позволяет использовать callable для параметра on_bad_lines, это позволяет применять более сложную обработку плохих строк.
Новое в версии 1.4.0:
callable, function with signature (bad_line: list[str]) -> list[str] | None that will process a single bad line. bad_line is aсписок строк, разделенных sep. Если функция возвращает None, плохая строка будет проигнорирована. Если функция возвращает новый список строки с большим количеством элементов, чем ожидалось, будет выдано предупреждение ParserWarning. испускается при отбрасывании дополнительных элементов. Поддерживается только тогда, когда двигатель = "питон"
Таким образом, вы можете передать пользовательскую функцию, которая запишет обнаруженную неверную строку в определенный файл и вернет None (чтобы пропустить эту строку при создании кадра данных).
from functools import partial
def write_bad_line(line, fp, sep=','):
fp.write(sep.join(line) + '\n')
return None # return None to skip the line while processing
bad_lines_fp = open('bad_lines.csv', 'a')
df = pd.read_csv('test.csv', header=None, sep=';', engine='python',
on_bad_lines=partial(write_bad_line, sep=';', fp=bad_lines_fp))
bad_lines_fp.close()
print(df)
Вывод фрейма данных:
0 1 2
0 1 Snow,Jon 19801201
1 2 Crom,Jake 19920103
Содержимое bad_lines.csv (через команду cat):
$ cat bad_lines.csv
003; ;Wise,Frank;19880303
004;Wiseau,Tommy;4324;1323;2323
pandas.read_csv— удобный инструмент, когда все совпадает идеально. Если у вас есть потребности, которые он не может удовлетворить, вам нужно использовать пакетcsvи прочитать файл самостоятельно.