← Все курсы · Курс Python · Все руководства
pandas.read_csv: ваш первый DataFrame и что он угадал
К концу этой страницы вы сможете загрузить CSV в pandas, за двадцать секунд узнать, какого типа стал каждый столбец, остановить потерю столбцов идентификаторов ведущих нулей, прочитать даты так, как они были написаны, и превратить столбец денег, полученный в виде текста, в числа. Это около двадцати пяти минут, и все приведенные ниже выходные данные были получены путем запуска кода.
Вот что нужно сделать сегодня, сразу после первой загрузки файла. Бегать df.dtypes. Нет df.head(), который показывает, как выглядят значения, но dtypes, который показывает вам, что они из себя представляют. Столбец идентификаторов, который говорит int64 уже потерял ведущие нули и столбец денег, в котором говорится object или str это текст, который не будет складываться.
Краткая версия: read_csv читает символы и угадывает тип по столбцу. Догадка обычно верна, если она неверна, она молчит, а четыре аргумента заменяют догадку инструкцией.
Идея состоит в том, что одни и те же персонажи становятся двумя разными значениями, поэтому картина понятна.
- Загрузите его, затем посмотрите на него
- Что он угадал и сколько это стоило
- Объявите типы
- Даты: назовите формат
- Отсутствующие значения отсутствуют только в том случае, если вы так говорите.
- Цифры со знаками препинания
- использование коллов, строки и ловушка индекса
- Блок проверки любого нового файла
- Полное до и после
- Краевые случаи, при которых нарушается нагрузка
- Почему это работает
- Использование этого в вашем собственном проекте
- Все на одном экране
Вот файл в виде символов. Четыре ряда, и из этого получается все, что есть на этой странице.
order_id,order_date,zip,rep,region,units,amount
1001,05/01/2026,08053,Dana Reyes,North,4,"1,234.50"
1002,12/01/2026,02134,Owen Park,South,10,"850.00"
1003,19/01/2026,00501,Priya Shah,East,N/A,"660.00"
1004,26/01/2026,90210,Dana Reyes,North,6,"240.00"
1. Загрузите его, затем посмотрите на него
Одна строка загружает его. Еще четыре расскажут вам, что вы получили, и пропустить их — ошибка, о которой идет вся эта страница.
import pandas as pd
df = pd.read_csv("orders.csv")
df.shape # (4, 7) rows and columns
df.dtypes # what each column became
df.head() # what the values look like
df.isna().sum() # how many are missing, per column
Бегите в таком порядке. shape против ожидаемого количества строк немедленно обнаруживает усеченный файл или проблему с разделителем. dtypes это то, что люди пропускают, и то, что имеет значение. head это для глаз. И isna().sum() это номер, который вас спросят позже.
добавлять df.describe() когда файл числовой. Он дает количество, среднее, минимальное, максимальное и квартили на числовой столбец, а полезная часть для первого взгляда — это Считать строка, поскольку в столбце, число которого меньше, чем количество строк, имеются пропущенные значения.
2. Что он угадал и сколько это стоило
Перед пояснением: файл выше загружается вообще без аргументов. Скажите, какой из семи столбцов, по вашему мнению, неправильный.
df = pd.read_csv("orders.csv")
order_id order_date zip rep region units amount
0 1001 05/01/2026 8053 Dana Reyes North 4.0 1,234.50
1 1002 12/01/2026 2134 Owen Park South 10.0 850.00
2 1003 19/01/2026 501 Priya Shah East NaN 660.00
3 1004 26/01/2026 90210 Dana Reyes North 6.0 240.00
Три проблемы, ни одна из которых ничего не вызвала.
Столбец молния потерял ведущие нули. 08053 стало 8053, а 00501 стало 501, потому что символы выглядели как числа и читались как одно. Информация исчезла из кадра; никакое переформатирование не вернет цифру, которая никогда не сохранялась.
Столбец суммы по-прежнему текстовый., из-за запятой в 1234,50. А текст, который выглядит числовым, при суммировании приводит к чему-то худшему, чем к ошибке:
df["amount"].sum()
'1,234.50850.00660.00240.00'
Это не число. sum текст объединяется, поэтому «итог» — это каждое значение, склеенное вместе, и если оно попадает в отчет в виде строки, никто не воспримет это как арифметическую ошибку.
Столбец единиц стал плавающим. Целые числа с единицей N/A среди них не могут все быть целыми числами, потому что недостающее должно быть представлено, поэтому pandas расширили столбец до float64 и значения теперь равны 4,0, 10,0, НЭН, 6,0. Это не порча, это сигнал: целочисленный столбец, который появляется как число с плавающей запятой, почти всегда означает, что в нем чего-то не хватает.
Скажите вслух, кто из этих троих будет виден в head() один. Нули, если вы знали, что они должны быть там. Остальные двое выглядят совершенно нормально.
3. Объявите типы
dtype принимает словарь имен и типов столбцов и применяется перед любым преобразованием, что позволяет сохранить нули.
df = pd.read_csv("orders.csv", dtype={"zip": "string", "order_id": "string"})
zip -> ['08053', '02134', '00501', '90210']
Все пять персонажей, каждый раз. Правило, которое стоит взять на вооружение: все, что что-то идентифицирует, а не измеряет, является текстом. Почтовые индексы, номера счетов, ссылки на заказы, коды продуктов, номера телефонов, идентификаторы сотрудников. Это тест из мира электронных таблиц: будет ли что-нибудь означать сложение двух из них вместе? Если нет, то это не число, как бы оно ни выглядело. Версия Excel именно этого сбоя находится в Диалог, который незаметно удаляет ваши почтовые индексы, и те же символы теряются в другом инструменте.
Два замечания по названиям типов. "string" — это современный тип строки pandas и что использовать; старый код говорит str и получает столбец общего объекта, который работает, но его назначение менее ясно. И объявление типа для одного столбца не мешает pandas угадывать остальные, поэтому dtype — это список исключений, а не полная схема, если вы ее не напишете.
4. Даты: назовите формат.
Перед пояснением: даты читайте 05/01/2026. Скажи, какой это день.
Вы не можете этого знать, и pandas тоже. Попросите его проанализировать их, не указывая, в каком порядке находятся фрагменты:
pd.read_csv("orders.csv", parse_dates=["order_date"])
dtype: str
first value: '05/01/2026'
Ничего не произошло. Столбец по-прежнему текстовый, никаких исключений не возникло, и если вы не проверили dtypes ты бы продолжал считать, что это свидание. Текущие pandas отказываются угадывать неоднозначный формат, а не выбирают его, что гораздо лучше, чем угадывание, и гораздо легче пропустить, чем ошибку.
Скажите формат, и он работает:
pd.read_csv("orders.csv", parse_dates=["order_date"], date_format="%d/%m/%Y")
['2026-01-05', '2026-01-12', '2026-01-19', '2026-01-26']
И вот что стоит знать, потому что это система безопасности. Объявляя неправильный формат также оставляет столбец в виде текста, а не выдает неправильные даты: запрашивая %m/%d/%Y по этому файлу возвращает str, поскольку 19.01 и 26.01 не являются допустимыми датами первого месяца. Таким образом, ошибка в формате отображается в dtypes а не в числах, если хотя бы одна строка в файле однозначна.
Это тоже предупреждение. Файл, в котором каждая дата имеет день двенадцать или меньше, совершенно неоднозначен, оба формата анализируются правильно, а неправильный дает вам рабочий столбец, полный неправильных дат. Это не проблема pandas, это свойство файла, и исправление состоит в том, чтобы запросить источник yyyy-mm-dd. Более широкая версия этого находится в как хранятся даты.
5. Отсутствующие значения отсутствуют только в том случае, если вы так говорите.
pandas распознает список маркеров как отсутствующий, включая пустые поля, NA, NaN, NULL и N/A. Вот почему units уже вернулся с NaN выше.
Чего он не распознает, так это того, что изобрела ваша исходная система. Реальное использование файлов -, none, Unknown, #N/A, 999, -1и одно пространство. Они поступают как обычные значения, что означает, что текстовый маркер составляет весь текст столбца, а числовой маркер, например -1 или 999 гораздо хуже: это реальное число, оно будет усреднено, и ничто никогда не будет выглядеть неправильно.
pd.read_csv("orders.csv", na_values=["N/A", "-", "Unknown", "none"])
Затем проверьте, что это дало, потому что счетчик — это результат:
df.isna().sum()
order_id 0
order_date 0
zip 0
units 1
amount 0
units: sum 20.0, count 3, rows 4
Одна недостающая стоимость единицы. Обратите внимание на последнюю строку: сумма столбца равна 20 при счете 3 в кадре из 4 строк. Число меньше количества строк является определением столбца с пропущенными значениями., и сравнение этих двух чисел — самая дешевая проверка в pandas. Что с ними делать, заполнить или удалить или оставить, это отдельное решение со своей страницей.
6. Цифры со знаками препинания
Столбец суммы остался текстовым из-за одной запятой. Один аргумент исправляет это во время чтения.
pd.read_csv("orders.csv", thousands=",")
df["amount"].sum() 2984.5
Число, которое в сумме составляет: 1234,50 плюс 850 плюс 660 плюс 240 — это 2984,50.
Трое родственников, файлы из других источников. decimal="," для европейских файлов, где запятая — это десятичная точка, а точка группирует тысячи. encoding="utf-8", или "latin-1", или "cp1252", когда символы с акцентом выглядят как тарабарщина. И sep=";" или sep="\t" когда файл на самом деле не разделен запятыми, что представляет собой фрейм с одним очень широким столбцом.
Символ валюты не покрывается thousands. £1,234.50 остается текст, и его нужно чистить после загрузки:
df["amount"] = (df["amount"].str.replace(r"[£$,]", "", regex=True).astype(float))
7. использование коллов, строки и ловушка индекса
Три аргумента, которые меняют объем загрузки, а не то, как это интерпретируется.
usecols читает только те столбцы, которые вы называете. В файле с девяностою столбцами и четырьмя необходимыми — это разница между фреймом, на который вы можете смотреть, и фреймом, который вы прокручиваете вбок, а также экономит память.
pd.read_csv("orders.csv", usecols=["order_id", "amount"])
nrows читает только первые несколько. Сначала направьте его на очень большой файл, определите нужные аргументы для двухсот строк, а затем загрузите все это один раз с правильными настройками. Это привычка, которая превращает медленный первый час в быстрый, а остальная часть проблемы «слишком большой, чтобы ее открыть» заключается в следующем. Обработка больших наборов данных.
index_col делает столбец индексом, а не столбцом, и это бросается в глаза новичкам, потому что столбец затем исчезает из df.columns и от всего, что перебирает столбцы.
df = pd.read_csv("orders.csv", index_col="order_id")
list(df.columns) # order_id is not in here any more
Используйте его сознательно, если идентификатор на самом деле является меткой строки и вы будете искать по ней строки вверх. В противном случае оставьте это в покое; числовой индекс по умолчанию подходит и сохраняет идентификатор там, где вы можете его увидеть.
8. Блок проверки любого нового файла
Шесть строк, запускаемых каждый раз перед любым анализом. Они занимают двадцать секунд и охватывают все, что есть на этой странице.
df.shape # does the row count match what you expected?
df.dtypes # is every column the type it should be?
df.head() # do the values look right?
df.isna().sum() # how many missing, per column?
df.describe() # count row lower than shape? min or max absurd?
df.nunique() # distinct values: is it the number you expected?
Последний заслуживает своего места больше, чем кажется. Столбец региона с шестью различными значениями, хотя вы знаете, что их четыре, — это проблема с правописанием, обнаруженная до того, как он станет отчетом с двумя дополнительными регионами.
Представьте себе последний файл, который вам кто-то прислал. Кто из этих шести мог бы сказать вам что-то, чего вы еще не знали, и запустили ли вы это?
Полное до и после
Тот же файл, те же четыре строки.
До
df = pd.read_csv("orders.csv")
zip 8053, 2134, 501, 90210 leading zeros gone
order_date '05/01/2026' text, not a date
amount '1,234.50' text
amount.sum() '1,234.50850.00660.00240.00' concatenated
Одна строка, четыре столбца неправильные, ни ошибок, ни предупреждений. Три из четырех невидимы, если вы не посмотрите на них. dtypes.
после
df = pd.read_csv(
"orders.csv",
dtype={"zip": "string", "order_id": "string"},
parse_dates=["order_date"], date_format="%d/%m/%Y",
na_values=["N/A", "-", "Unknown"],
thousands=",",
)
order_id string
order_date datetime64[us]
zip string
units float64
amount float64
zip '08053', '02134', '00501', '90210'
amount.sum() 2984.5
units sum 20.0, count 3, rows 4 one value missing
Претензия и вот почему dtypes это первая команда, а не четвертая: один и тот же файл, загруженный двумя способами, дает 2984,50 или любую сумму, склеенную в одну строку, и единственная разница, видимая на экране, - это слово str в строке большинство людей никогда не печатает.
Краевые случаи, при которых нарушается нагрузка
Шесть, которые стоит знать.
Смешанные типы в одном столбце. Если столбец является числовым для ста тысяч строк, а затем содержит "pending", pandas читает файл по частям и может создать столбец смешанных типов. Объявление dtype устраняет такую возможность.
Очень большие целые числа. Номер счета, состоящий из девятнадцати цифр, превышает то, что может содержать целочисленный столбец, и последние цифры меняются. Другая причина, по которой идентификаторы — это текст.
Заголовок, которого нет в первой строке. Две строки заголовков над данными превращают первый заголовок в имена столбцов, а все остальное — в строки. Использовать skiprows=2, или header=2.
Дополнительные запятые внутри полей в кавычках. По умолчанию обрабатывается правильно и нарушается из-за файлов, которые цитируют непоследовательно. Симптомом является кадр, в котором столбцов больше, чем в заголовке.
Завершающие пустые строки и нижние колонтитулы. Строка итогов внизу становится строкой данных, содержащей текст в ваших числовых столбцах, что часто и приводит к тому, что столбец в первую очередь превращается в текст. skipfooter существует; лучше удалить строку в источнике.
Пробелы вокруг значений. " North" и "North" это разные значения и они будут отображаться в nunique. skipinitialspace=True обрабатывает общий случай, а остальное — обычная процедура очистки.
Почему это работает
CSV-файл не содержит типов. Это символы и разделители, и ничто в них не говорит о том, является ли 08053 числом или меткой, поэтому читатель должен решить, а pandas решает, проверяя значения. Этот вывод является сознательным выбором дизайна, а не недосмотром: библиотека была построена на идее, что загрузка реальных, беспорядочных, табличных данных должна занимать одну строку и немедленно создавать что-то пригодное для использования, с возможностью настройки для случаев, когда предположение неверно (МакКинни, 2010, Материалы 9-й конференции «Питон в науке», 51–56). Удобство реальное. Цена состоит в том, что момент предположения становится невидимым, поэтому дисциплина заключается не в том, чтобы избежать вывода, а в том, чтобы проверить его один раз в каждом файле.
Причина, по которой следует уделять непропорционально большое внимание столбцам идентификаторов, заключается в том, что потеря не подлежит восстановлению и не видна. Это та же ошибка, которая привела к хорошо документированной проблеме в опубликованной науке, где программное обеспечение для работы с электронными таблицами автоматически преобразовывало названия генов в даты и числа, а преобразованные значения выдерживали экспертную оценку, поскольку преобразованная клетка выглядит точно так же, как обычная (Циманн, Эрен и Эль-Оста, 2016, Геномная биология, 17, 177). Почтовый индекс, который стал 8053, обладает тем же свойством: это вполне правдоподобный номер, он ни с чем не соединится, и ошибка будет проявляться как отсутствие совпадений, а не как ошибка.
Одно замечание в шпаргалке ниже. Он создан для того, чтобы его просматривали и вспоминали, а не перечитывали, поскольку преимущество самопроверки перед повторным изучением справедливо для сложного, реалистичного материала, а не только для списков слов (выбирать карпа & Ой, 2015, Обзор педагогической психологии, 27(2), 317–326).
Использование этого в вашем собственном проекте
Переписывать каждую загрузку в старом блокноте – унылое занятие. Вместо этого сделайте это по порядку.
- распечатать
dtypesсразу после каждого прочтения. Одна строчка, и это целый диагноз. - Объявите каждый столбец идентификатора как
"string", прежде всего. Это необратимая потеря. - Дайте каждому свиданию
date_formatи затем проверьте dtype, чтобы убедиться, что это произошло. - Перечислите недостающие маркеры вашего источника в
na_values, а затем посмотритеisna().sum()вместо того, чтобы предполагать, что оно равно нулю. - Использовать
nrowsчтобы проработать аргументы в большом файле, а затем загрузите его один раз правильно. - Сохраните блок проверки из шести строк в верхней части каждого блокнота и запускайте его для каждого нового файла.
Если у вас под рукой есть бумага, один дополнительный эскиз стоит пяти минут. Запишите имена столбцов вашего файла и рядом с каждым укажите тип, которым он должен быть, и почему: мера или метка, дата или текст, разрешено ли отсутствовать или нет. Этот список твой dtype словарь и твой na_values список, и его написание занимает меньше времени, чем потом выяснять, какая из pandas ошиблась.
Все на одном экране
Это лист поиска. Закройте правую колонку, проработайте левую и произнесите каждый ответ вслух, прежде чем проверять его.
| вещь | Что он делает |
|---|---|
| Первая команда после загрузки | df.dtypes. Не голова. |
| CSV не имеет типов | pandas молча выводит по одному на столбец. |
| Идентификатор читается как число | Ведущие нули исчезли безвозвратно. |
| Тест | Будет ли добавление двух из них означать что-нибудь? Если нет, то это текст. |
dtype={"zip": "string"} | Применяется до преобразования, поэтому персонажи выживают. |
| Текст, который выглядит числовым | sum() объединяет вместо добавления. |
| Целочисленный столбец, поступающий как число с плавающей запятой | Чего-то в нем не хватало. |
parse_dates один | Отклоняет неоднозначный формат и оставляет его как текст. |
date_format="%d/%m/%Y" | Говорит, в каком порядке расположены детали. |
| Неправильный формат | Также оставляет его как текст, если какая-либо строка однозначна. |
| Обнаружены недостающие маркеры | Пусто, NA, НЭН, NULL, Н/Д. Не твой. |
na_values=[...] | Маркеры вашего источника. Числовой маркер типа -1 опасен. |
thousands="," | Превращает «1234,50» в число во время чтения. |
| Символы валют | Не покрыто. Разденьте их после загрузки. |
usecols, nrows | Меньше столбцов, меньше строк. Настройтесь на образец, загрузите один раз. |
index_col | Колонна уходит df.columns. Используйте сознательно. |
| Контрольный блок | форма, типы данных, голова, слишком().сумма(), описание, уникальный. |
df.dtypes прежде чем делать что-либо еще с новым кадром каждый раз. Каждая ошибка на этой странице видна в этом одном выводе и невидима во всех остальных, и в любом случае она стоит одну строку вверху ячейки, которую вы пишете. Если нагрузка ведет себя не так, как описано на этой странице, существует общая причина. шлейф диагностики на предмет застревания.Еще одна мысль, и мне бы искренне хотелось услышать ответы других людей. У меня был файл клиентов, в котором номера счетов загружались как целые числа, поэтому каждая учетная запись, начинающаяся с нуля, не могла присоединиться к выписке о счетах, а пропавшие клиенты большую часть квартала выглядели как отток. Чего вам стоит угадать тип?
Ссылки
- МакКинни, В. (2010). Структуры данных для статистических вычислений в Питон. Материалы 9-й конференции «Питон в науке», 51–56.
- Циманн М., Эрен Ю. и Эль-Оста А. (2016). Ошибки в названиях генов широко распространены в научной литературе. Геномная биология, 17, 177.
- Карпике Дж. Д. и Ауэ В. Р. (2015). Эффект тестирования жив и здоров со сложными материалами. Обзор педагогической психологии, 27(2), 317–326.
Python для аналитиков составляет 203 страницы, read_csv читается аргумент за аргументом, включая типы типы данных, которые предотвращают неправильное угадывание столбца.
Python для аналитиков, 19 $ →тот Курс Python дает вам повторения: CSV-файлы, заполненные ведущими нулями, неоднозначными датами и изобретенными отсутствующими маркерами, а также флеш-карточки, на которых аргумент фиксирует какой симптом, и пробный экзамен, который спрашивает, каким будет dtype столбца, прежде чем вы его загрузите. Теперь вы владеете методом; комплект - это практика. Ничего устанавливать, учетная запись не требуется.
Откройте комплект Python →