← Все курсы · Курс Python · Все руководства

pandas.read_csv: ваш первый DataFrame и что он угадал

Одна строка, чтобы загрузить его, четыре, чтобы узнать, что он сделал · Часть Analyst Prep Kit

К , аналитик данных · Опубликовано

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

Вот что нужно сделать сегодня, сразу после первой загрузки файла. Бегать df.dtypes. Нет df.head(), который показывает, как выглядят значения, но dtypes, который показывает вам, что они из себя представляют. Столбец идентификаторов, который говорит int64 уже потерял ведущие нули и столбец денег, в котором говорится object или str это текст, который не будет складываться.

Краткая версия: read_csv читает символы и угадывает тип по столбцу. Догадка обычно верна, если она неверна, она молчит, а четыре аргумента заменяют догадку инструкцией.

Идея состоит в том, что одни и те же персонажи становятся двумя разными значениями, поэтому картина понятна.

The same characters, two different values On the left, a strip of five small square boxes holds one character each, reading zero, eight, zero, five, three, as the characters appear in the file. Two arrows branch out from that strip. The upper arrow leads to a strip of five boxes in which the first box is empty, crossed through and outlined in amber, while the remaining four hold eight, zero, five and three; the leading character has been discarded. The lower arrow leads to a strip of five boxes holding zero, eight, zero, five and three, identical to the original, outlined in blue. Both destinations came from the same source strip, and only one of them still contains everything the file did. 080 53 8053 080 53
Пять символов в файле. Читается как число: первое из них исчезло и не может быть восстановлено из того, что осталось. Прочтите как текст: все пятеро выживут. Ничто в файле не определяло, что произошло.
Что вы узнаете
  1. Загрузите его, затем посмотрите на него
  2. Что он угадал и сколько это стоило
  3. Объявите типы
  4. Даты: назовите формат
  5. Отсутствующие значения отсутствуют только в том случае, если вы так говорите.
  6. Цифры со знаками препинания
  7. использование коллов, строки и ловушка индекса
  8. Блок проверки любого нового файла
  9. Полное до и после
  10. Краевые случаи, при которых нарушается нагрузка
  11. Почему это работает
  12. Использование этого в вашем собственном проекте
  13. Все на одном экране
Каждый вывод на этой странице реален. Запустите на pandas 3.0.2 небольшой CSV-файл, созданный для устранения четырех проблем, с которыми сталкивается каждый реальный экспорт: идентификатор с ведущими нулями, неоднозначные даты, текстовый маркер для пропущенных значений и деньги с разделителем тысяч. Если ваши pandas старше, аргументы те же, но одно или два поведения по умолчанию отличаются, что отмечается там, где это важно.

Вот файл в виде символов. Четыре ряда, и из этого получается все, что есть на этой странице.

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).

Использование этого в вашем собственном проекте

Переписывать каждую загрузку в старом блокноте – унылое занятие. Вместо этого сделайте это по порядку.

  1. распечатать dtypes сразу после каждого прочтения. Одна строчка, и это целый диагноз.
  2. Объявите каждый столбец идентификатора как "string", прежде всего. Это необратимая потеря.
  3. Дайте каждому свиданию date_formatи затем проверьте dtype, чтобы убедиться, что это произошло.
  4. Перечислите недостающие маркеры вашего источника в na_values, а затем посмотрите isna().sum() вместо того, чтобы предполагать, что оно равно нулю.
  5. Использовать nrows чтобы проработать аргументы в большом файле, а затем загрузите его один раз правильно.
  6. Сохраните блок проверки из шести строк в верхней части каждого блокнота и запускайте его для каждого нового файла.

Если у вас под рукой есть бумага, один дополнительный эскиз стоит пяти минут. Запишите имена столбцов вашего файла и рядом с каждым укажите тип, которым он должен быть, и почему: мера или метка, дата или текст, разрешено ли отсутствовать или нет. Этот список твой dtype словарь и твой na_values список, и его написание занимает меньше времени, чем потом выяснять, какая из pandas ошиблась.

Подробнее об этом и еще что-нибудь подобное. Все инструкции находятся в одном месте на индекс направляющих: Python, SQL, Excel и связанные с ними рабочие привычки. Следующим шагом после загрузки обычно является подведение итогов, то есть pandas.groupby.

Все на одном экране

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

вещьЧто он делает
Первая команда после загрузки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 прежде чем делать что-либо еще с новым кадром каждый раз. Каждая ошибка на этой странице видна в этом одном выводе и невидима во всех остальных, и в любом случае она стоит одну строку вверху ячейки, которую вы пишете. Если нагрузка ведет себя не так, как описано на этой странице, существует общая причина. шлейф диагностики на предмет застревания.

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

Ссылки

Файл загружен, и столбец идентификатора потерял ведущие нули еще до того, как вы увидели единственную строку.

Python для аналитиков составляет 203 страницы, read_csv читается аргумент за аргументом, включая типы типы данных, которые предотвращают неправильное угадывание столбца.

Python для аналитиков, 19 $ →
Попрактикуйтесь в загрузке файлов, которые сопротивляются.

тот Курс Python дает вам повторения: CSV-файлы, заполненные ведущими нулями, неоднозначными датами и изобретенными отсутствующими маркерами, а также флеш-карточки, на которых аргумент фиксирует какой симптом, и пробный экзамен, который спрашивает, каким будет dtype столбца, прежде чем вы его загрузите. Теперь вы владеете методом; комплект - это практика. Ничего устанавливать, учетная запись не требуется.

Откройте комплект Python →