Чтение плохих CSV-файлов со значениями мусора
Я хочу прочитать CSV-файл, который имеет следующий формат, используя панды:
atrrth
sfkjbgksjg
airuqghlerig
Name Roll
airuqgorqowi
awlrkgjabgwl
AAA 67
BBB 55
CCC 07
Как видите, если я использую pd.read_csv
Я получаю довольно очевидную ошибку:
ParserError: Error tokenizing data. C error: Expected 1 fields in line 4, saw 2
Но я хочу получить все данные в рамках данных. С помощью error_bad_lines = False
удалит важные вещи и оставит только мусорные значения
Это 2 из возможных имен столбцов, как указано ниже:
Name : [Name , NAME , Name of student]
Roll : [Rollno , Roll , ROLL]
Как этого добиться?
3 ответа
Откройте файл CSV и найдите строку, откуда начинается имя столбца:
with open(r'data.csv') as fp:
skip = next(filter(
lambda x: x[1].startswith(('Name','NAME')),
enumerate(fp)
))[0]
Значение будет сохранено в skip
параметр
import pandas as pd
df = pd.read_csv('data.csv', skiprows=skip)
Работает в Python 3.X
Я хотел бы предложить небольшое изменение / упрощение ответа @RahulAgarwal. Вместо того, чтобы закрывать и повторно открывать файл, вы можете продолжить загрузку того же потока прямо в панды. Вместо того, чтобы записывать количество пропускаемых строк, вы можете записать строку заголовка и разделить ее вручную, чтобы указать имена столбцов:
with open(r'data.csv') as fp:
names = next(line for line in fp if line.casefold().lstrip().startswith('name'))
df = pd.read_csv(fp, names=names.strip().split())
Это имеет преимущество для файлов с большим количеством строк мусора.
Более детальная проверка может быть примерно такой:
def isheader(line):
items = line.strip().split()
if len(items) != 2:
return False
items = sorted(map(str.casefold, items))
return items[0].startswith('name') and items[1].startswith('roll')
Эта функция будет обрабатывать все ваши возможности в любом порядке, но также в настоящее время пропускает строки мусора с пробелами в них. Вы бы использовали его в качестве фильтра:
names = next(line for line in fp if isheader(line))
Если это действительно структура (а не просто пример того, какой мусор можно получить), вы можете просто использовать аргумент skiprows, чтобы указать, сколько строк следует пропустить. Другими словами, вы должны прочитать свой фрейм данных следующим образом:
import pandas as pd
df = pd.read_csv('your.csv', skiprows=3)
Имейте в виду, что skiprows
может сделать гораздо больше Проверьте документы.