2025, Oct 04 07:16
Как обработать нечисловые runtimeMinutes в IMDB с pandas
Как исправить в pandas ошибку ValueError при чтении IMDB title.basics.tsv: выявляем нечисловые runtimeMinutes, добавляем их в na_values и загружаем как Int64.
Разбор файла IMDB title.basics.tsv с помощью pandas кажется простым, пока простое приведение типа не рушится с ошибкой ValueError: Unable to parse string "Reality-TV". Сбивает с толку то, что указанная в сообщении позиция может не совпадать с тем, что видно вокруг этой строки в исходном файле. Вместо охоты за номерами строк полезнее подтвердить, что действительно хранится в runtimeMinutes, и явно обработать нечисловые маркеры.
Воспроизводим ошибку
Типичный шаг загрузки — принудительно задать допускающий пропуски целочисленный тип через Int64 в pandas и считать "\N" отсутствующим значением. Ровно на этом месте и возникает сбой.
import pandas as pd
movie_data = pd.read_csv("title.basics.tsv",
sep="\t",
dtype={
"runtimeMinutes": "Int64",
},
na_values={
"runtimeMinutes": ["\\N"],
})
Исключение ValueError: Unable to parse string "Reality-TV" показывает, что в столбце встречаются значения, которые не являются числами и не покрыты текущим сопоставлением na_values.
Что на самом деле вызывает ошибку
Поле runtimeMinutes должно быть числовым, но на практике там встречаются и строковые значения. Эти текстовые токены нельзя привести к Int64 на этапе read_csv, отсюда и ошибка разбора. Практичный путь — перечислить уникальные значения, которые блокируют приведение, и пометить их как пропуски при загрузке.
Поиск нечисловых значений
Ниже фрагмент, который читает файл без принудительного dtype для runtimeMinutes, просматривает уникальные значения и собирает всё, что не проходит int(). Он также печатает проблемные значения, чтобы явно зафиксировать некорректные данные.
import pandas as pd
raw_frame = pd.read_csv("title.basics.tsv",
sep="\t",
na_values={
"runtimeMinutes": ["\\N"],
})
def extract_bad_markers(tbl, field_name):
anomalies = []
print(f"{'Type':20} | {'Value'}")
print('-'*53)
for item in tbl[field_name].unique():
try:
int(item)
except:
print(f"{str(type(item)):20} | {item}")
anomalies.append(item)
print("\nIncorrect values:", anomalies)
return anomalies
invalid_values = extract_bad_markers(raw_frame, "runtimeMinutes")
Именно присутствие строк вроде "Reality-TV" в runtimeMinutes и вызывает ошибку парсинга.
Чистая загрузка: помечаем нечисловые значения как NA
Когда набор недопустимых маркеров известен, укажите read_csv трактовать их как пропуски вместе с "\N". Тогда pandas сможет безопасно загрузить столбец как Int64.
invalid_values.append("\\N")
clean_titles = pd.read_csv("title.basics.tsv",
sep="\t",
dtype={
"runtimeMinutes": "Int64",
},
na_values={
"runtimeMinutes": invalid_values,
})
При первом запуске этот подход может занять больше времени, потому что перед финальной загрузкой вы сканируете уникальные значения. Зато дальше у вас будет надёжный шаг ингеста: после первичного прохода можно сохранить корректно обработанный DataFrame и использовать его напрямую.
Зачем это нужно в вашем конвейере данных
Предположения о схеме хрупки, когда в реальных наборах данных в одном поле смешиваются типы. Явно обнаружив и объявив все нечисловые токены как NA, вы делаете парсер детерминированным, сохраняете семантику nullable-целых и не гоняетесь за вводящими в заблуждение позициями из сообщений об ошибках. В результате получается воспроизводимый шаг загрузки, который падает реже и документирует особенности данных, которые придётся учитывать дальше по конвейеру.
Выводы
Если приведение dtype в pandas срывается, проверьте фактическую область значений столбца вместо того, чтобы полагаться на ожидания. Сначала считайте данные без dtype, перечислите уникальные значения и соберите всё, что не удаётся преобразовать через int(). Передайте этот набор в na_values и перезагрузите с целевым dtype. В случае IMDB title.basics.tsv это превращает runtimeMinutes в корректный столбец Int64, трактуя неожиданные строки, включая "\N", как пропуски. Сохраните очищенный датасет, чтобы в следующий раз пропустить этап обнаружения и держать конвейер быстрым и предсказуемым.