Библиотека Pandas для Python
Оглавление
- Введение в панд
- О данных
- Установка
- Загрузка данных
- Основные операции
- Dtype
- Очистка и преобразование данных
- Выполнение основных операций
- Экспорт преобразованных данных
- Финальные заметки
Знакомство с пандами
Итак, что такое Pandas - практически говоря? Если коротко, то это основная библиотека анализа данных для Python. Для ученых, студентов и профессиональных разработчиков Pandas является основной причиной для изучения или взаимодействия с Python, в отличие от специфического языка статистики, такого как R, или проприетарного академического пакета, такого как SPSS или Matlab. (Интересный факт - Pandas назван в честь термина Panel Data, и изначально был создан для анализа таблиц финансовых данных). Мне нравится думать, что последняя буква "s" означает Series или Statistics.
Хотя существует множество способов исследовать числовые данные с помощью Python "из коробки", все они будут включать в себя довольно низкопроизводительные результаты с тонной шаблонов. В это трудно поверить, но Pandas часто рекомендуют в качестве следующей остановки для пользователей Excel, которые готовы поднять анализ данных на новый уровень. Почти любая проблема, которую можно решить с помощью программы электронных таблиц, может быть решена в Pandas - без всяких графических излишеств.
Более того, поскольку проблемы можно решать в Pandas с помощью Python, решения уже автоматизированы или могут быть запущены как сервис в облаке. Кроме того, Pandas активно использует Numpy, полагаясь на его низкоуровневые вызовы для получения результатов линейной математики на порядки выше Mag
О данных
В этой заметке мы будем использовать интересный набор данных, чтобы продемонстрировать полезный фрагмент библиотеки Pandas. Этот набор данных особенно интересен, поскольку он является частью примера из реального мира, и мы все можем представить себе людей, выстроившихся в очередь в аэропорту (место, где время от времени все идет не так). Глядя на эти данные, я представляю, как люди, сидящие в неудобных креслах в аэропорту, только что обнаружили, что их багаж пропал - не просто временно, но его нигде нет в системе! Или, что еще лучше, представьте, что трудолюбивый сотрудник TSA случайно разбил драгоценную семейную реликвию.
Поэтому, конечно же, пришло время заполнить еще одну форму. Теперь получение данных из форм - интересный процесс с точки зрения сбора данных, поскольку у нас есть набор данных, которые происходят в определенное время. Это фактически означает, что мы можем интерпретировать записи как временной ряд. Кроме того, поскольку люди предоставляют информацию, мы можем узнать кое-что о группе людей.
Вернемся к нашему примеру: допустим, мы работаем в TSA, и нам поручено получить некоторые сведения о том, когда эти несчастные случаи наиболее вероятны, и дать некоторые рекомендации по улучшению работы службы.
Pandas, к счастью, является универсальным инструментом для изучения и анализа этого набора данных. Не стесняйтесь загрузить файл excel в папку проекта, чтобы начать работу, или выполните команду curl, приведенную ниже. Да, pandas может читать файлы .xls или .xlsx с помощью одного вызова команды pd.read_excel()
! На самом деле, новичкам, имеющим опыт работы с файлами .csv или excel, часто полезно подумать о том, как они решали бы проблему в excel, а затем понять, насколько проще это может быть в Pandas.
Итак, без лишних слов, откройте терминал, текстовый редактор или вашу любимую IDE и посмотрите сами, используя руководство, приведенное ниже.
Пример данных:
Взять, к примеру, некоторые претензии, предъявленные TSA в процессе досмотра людей или имущества пассажира в связи с травмой, потерей или повреждением. Информация о претензиях включает номер претензии, дату инцидента, тип претензии, сумму претензии, статус и решение.
Каталог: TSA Claims Data
Скачать наши данные: claims-2014.xls
Настройка
Для начала давайте создадим чистый каталог. Вы можете поместить его куда угодно или создать папку проекта в IDE. Используйте выбранный вами метод установки для получения Pandas: Pip, вероятно, самый простой.
$ mkdir -p ~/Desktop/pandas-tutorial/data && cd ~/Desktop/pandas-tutorial
Установите pandas вместе с xldr для загрузки файлов в формате Excel, matplotlib для построения графиков и Numpy для математических функций высокого уровня.
$ pip3 install matplotlib numpy pandas xldr
Опционально: загрузить данные примера с помощью curl:
$ curl -O https://www.dhs.gov/sites/default/files/publications/claims-2014.xls
Запуск Python:
$ python3
Python 3.7.1 (default, Nov 6 2018, 18:46:03)
[Clang 10.0.0 (clang-1000.11.45.5)] on darwin
Type "help", "copyright", "credits" or "license" for more information.
>>>
Импортировать пакеты:
>>> import matplotlib.pyplot as plt
>>> import numpy as np
>>> import pandas as pd
Загрузка данных
Загружать данные в Pandas очень просто. Pandas может точно считывать данные практически из любого распространенного формата, включая JSON, CSV и SQL. Данные загружаются во "флагманскую" структуру данных Pandas - DataFrame.
Это термин, который вы захотите запомнить. Вы будете часто слышать о DataFrames. Если этот термин кажется вам непонятным, подумайте о таблице в базе данных или о листе в Excel. Главное, что здесь больше одного столбца: каждая строка или запись имеет несколько полей, которые последовательны от строки к строке.
Вы можете загрузить примерные данные прямо из Интернета:
>>> df = pd.read_excel(io='https://www.dhs.gov/sites/default/files/publications/claims-2014.xls', index_col='Claim Number')
Менее круто, данные могут быть загружены из файла:
$ curl -O https://www.dhs.gov/sites/default/files/publications/claims-2014.xls
>>> df = pd.read_excel(io='claims-2014.xls', index_col='Claim Number')
Основные операции
Выведите информацию о DataFrame, включая dtype индекса и dtypes столбцов, значения non-null и использование памяти. DataFrame.info()
является одним из более полезных и универсальных методов, привязанных к DataFrame (их почти 150!).
>>> df.info()
'pandas.core.frame.dataframe'="">
Int64Index: 8855 entries, 2013081805991 to 2015012220083
Data columns (total 10 columns):
Date Received 8855 non-null datetime64[ns]
Incident Date 8855 non-null datetime64[ns]
Airport Code 8855 non-null object
Airport Name 8855 non-null object
Airline Name 8855 non-null object
Claim Type 8855 non-null object
Claim Site 8855 non-null object
Item Category 8855 non-null object
Close Amount 8855 non-null object
Disposition 8855 non-null object
dtypes: datetime64[ns](2), object(8)
memory usage: 761.0+ KB
Просмотреть первые n строк:
>>> df.info()
'="">>> df.head(n=3) # see also df.tail()
Claim Number Date Received Incident Date Airport Code ... Claim Site Item Category Close Amount Disposition
0 2013081805991 2014-01-13 2012-12-21 00:00:00 HPN ... Checked Baggage Audio/Video; Jewelry & Watches 0 Deny
1 2014080215586 2014-07-17 2014-06-30 18:38:00 MCO ... Checked Baggage - 0 Deny
2 2014010710583 2014-01-07 2013-12-27 22:00:00 SJU ... Checked Baggage Food & Drink 50 Approve in Full
[3 rows x 11 columns]
Перечислите все столбцы в DataFrame:
>>> df.columns
Index(['Claim Number', 'Date Received', 'Incident Date', 'Airport Code',
'Airport Name', 'Airline Name', 'Claim Type', 'Claim Site',
'Item Category', 'Close Amount', 'Disposition'],
dtype='object')
Возвращает один столбец (важно - также называется Series):
>>> df['Claim Type'].head()
0 Personal Injury
1 Property Damage
2 Property Damage
3 Property Damage
4 Property Damage
Name: Claim Type, dtype: object
Надеемся, вы начинаете понимать, что представляют собой данные claims-2014.xls.
Dtype
Типы данных - это фундаментальная концепция, которую необходимо хорошо знать, чтобы избежать разочарований в дальнейшем. Pandas использует номенклатуру Numpy, называя тип данных столбца его dtype
. Pandas также пытается вывести dtypes
при построении DataFrame (т.е. инициализации).
Чтобы воспользоваться преимуществами повышения производительности, присущими Numpy, нам нужно познакомиться с этими типами и узнать, как они примерно переводятся в типы родного Python.
Смотрите еще раз на df.info()
и обратите внимание на dtype
assig
>>> df.info()
'pandas.core.frame.dataframe'="">
RangeIndex: 8855 entries, 0 to 8854
Data columns (total 11 columns):
Date Received 8855 non-null datetime64[ns]
Incident Date 8855 non-null datetime64[ns]
Airport Code 8855 non-null object
Airport Name 8855 non-null object
Airline Name 8855 non-null object
Claim Type 8855 non-null object
Claim Site 8855 non-null object
Item Category 8855 non-null object
Close Amount 8855 non-null object
Disposition 8855 non-null object
dtypes: datetime64[ns](2), object(8)
memory usage: 761.1+ KB
dtypes
аналогичны настройкам формата текста/чисел, типичным для большинства приложений электронных таблиц, а Pandas использует dtypes
для определения того, какой тип (типы) операций может быть выполнен над данными в конкретном столбце. Например, математические операции можно выполнять только над числовыми типами данных, такими как int64 или float64. Столбцы, содержащие действительные даты и/или значения времени, назначаются
Короче говоря, Pandas пытается сделать вывод dtypes
при построении DataFrame. Однако, как и во многих приложениях для анализа данных, этот процесс не всегда идеален.
Важно отметить, что Pandas dtype
делает выводы с осторожностью: если серия содержит более одного типа данных, она назначается
Очистка и преобразование данных
Данные почти всегда грязные: они почти всегда содержат некоторые данные с нетипичным форматированием; некоторые артефакты, уникальные для среды их происхождения. Поэтому очистка данных имеет решающее значение для обеспечения достоверности анализа. Работа по очистке данных в Pandas в первую очередь включает в себя выявление и повторную обработку неверно выведенных значений dtypes
.
>>> df.dtypes
Date Received datetime64[ns]
Incident Date datetime64[ns]
Airport Code object
Airport Name object
Airline Name object
Claim Type object
Claim Site object
Item Category object
Close Amount object
Disposition object
dtype: object
Вновь взглянув на dtypes
нашего DataFrame, мы видим, что Pandas правильно определил dtypes
дату получения и дату инцидента как datetime64 dtypes
. Таким образом, атрибуты datetime данных столбца доступны во время операций. Например, для обобщения данных по часам дня, когда произошел каждый инцидент, мы можем сгруппировать и обобщить данные по элементу hour столбца datetime64, чтобы определить, в какие часы дня происходят определенные типы инцидентов.
>>> grp = df.groupby(by=df['Incident Date'].dt.hour)
>>> grp['Item Category'].describe()
count unique top freq
Incident Date
0 3421 146 Baggage/Cases/Purses 489
1 6 5 Other 2
2 11 9 - 2
3 5 5 Jewelry & Watches 1
4 49 18 Baggage/Cases/Purses 6
5 257 39 - 33
6 357 54 - 43
7 343 43 Clothing 41
8 299 47 - 35
9 305 41 - 31
10 349 45 Other 43
11 343 41 - 45
12 363 51 Other 41
13 359 55 - 45
14 386 60 Baggage/Cases/Purses 49
15 376 51 Other 41
16 351 43 Personal Electronics 35
17 307 52 Other 34
18 289 43 Baggage/Cases/Purses 37
19 241 46 Baggage/Cases/Purses 26
20 163 31 Baggage/Cases/Purses 23
21 104 32 Baggage/Cases/Purses 20
22 106 33 Baggage/Cases/Purses 19
23 65 25 Baggage/Cases/Purses 14
Это работает совершенно идеально - однако, обратите внимание, что Close Amount была загружена как object
. Слова типа "Amount" являются хорошим индикатором того, что столбец содержит числовые значения.
Давайте посмотрим на значения в Close Amount.
>>> df['Close Amount'].head()
0 0
1 0
2 50
3 0
4 0
Name: Close Amount, dtype: object
По-моему, они выглядят как числовые значения. Давайте посмотрим на другой конец
>>> df['Close Amount'].tail()
8850 0
8851 800
8852 0
8853 256
8854 -
Name: Close Amount, dtype: object
Вот виновник: индекс # 8854 является строковым значением.
Если Pandas не может объективно определить, что все значения, содержащиеся в столбце DataFrame, являются одинаковыми числовыми или датой/временем dtype
, то по умолчанию используется объект.
К счастью, я знаю по опыту, что формат чисел "Бухгалтерский учет" Excel обычно форматирует 0,00 как тире, -.
Итак, как это исправить? Pandas предоставляет общий метод DataFrame.apply, который можно использовать для применения любой одноаргументной функции к каждому значению одного или нескольких столбцов.
В данном случае мы будем использовать его для одновременного преобразования символа - в значение, которое он представляет в Excel, 0.0, и пересчета исходного объекта всего столбца dtype
в его правильный объект dtype
float64.
Сначала определим новую функцию для выполнения преобразования:
>>> def dash_to_zero(x):
>>> if '-' in str(x):
>>> return float() # 0.0
>>> else:
>>> return x # just return the input value as-is
Затем применим функцию к каждому значению Close Amount:
>>> df['Close Amount'] = df['Close Amount'].apply(dash_to_zero)
>>> df['Close Amount'].dtype
dtype('float64')
Эти два шага также можно объединить в однострочную операцию, используя лямбду Python:
>>> df['Close Amount'].apply(lambda x: 0. if '-' in str(x) else x)
Выполнение базового анализа
После того как вы убедились, что ваш набор данных "чист", вы готовы к анализу данных! Агрегирование - это процесс получения суммарных данных, которые могут быть более полезными, чем те мелкозернистые значения, которые мы получили для начала.
Вычисления
>>> df.sum()
Close Amount 538739.51
dtype: float64
>>> df.min()
Date Received 2014-01-01 00:00:00
Incident Date 2011-08-24 08:30:00
Airport Code -
Airport Name Albert J Ellis, Jacksonville
Airline Name -
Claim Type -
Claim Site -
Item Category -
Close Amount 0
Disposition -
>>> df.max()
Date Received 2014-12-31 00:00:00
Incident Date 2014-12-31 00:00:00
Airport Code ZZZ
Airport Name Yuma International Airport
Airline Name XL Airways
Claim Type Property Damage
Claim Site Other
Item Category Travel Accessories; Travel Accessories
Close Amount 25483.4
Disposition Settle
dtype: object
Booleans
Найдите все строки, в которых Close Amount
больше нуля. Это полезно, потому что мы хотим увидеть несколько паттеринов, где сумма действительно положительна, и показать, как работают условные операторы.
>>> df[df['Close Amount'] > 0].describe()
Close Amount
count 2360.000000
mean 228.279453
std 743.720179
min 1.250000
25% 44.470000
50% 100.000000
75% 240.942500
max 25483.440000
Группировка
В этом примере мы рассмотрим, как группировать по значениям одного столбца.
Объект Groupby - это промежуточный шаг, который позволяет нам агрегировать несколько строк, которые имеют что-то общее - в данном случае, значение диспозиции. Это полезно, поскольку мы получаем вид с высоты птичьего полета на различные категории данных. В конечном итоге мы используем describe()
для просмотра нескольких агрегатов одновременно.
>>> grp = df.groupby(by='Disposition')
>>> grp.describe()
Close Amount
count mean std min 25% 50% 75% max
Disposition
- 3737.0 0.000000 0.000000 0.00 0.0000 0.000 0.0000 0.00
Approve in Full 1668.0 158.812116 314.532028 1.25 32.9625 79.675 159.3375 6183.36
Deny 2758.0 0.000000 0.000000 0.00 0.0000 0.000 0.0000 0.00
Settle 692.0 395.723844 1268.818458 6.00 100.0000 225.000 425.6100 25483.44
Группировка по нескольким столбцам:
>>> grp = df.groupby(by=['Disposition', 'Claim Site'])
>>> grp.describe()
Close Amount
count mean std min 25% 50% 75% max
Disposition Claim Site
- - 34.0 0.000000 0.000000 0.00 0.0000 0.000 0.0000 0.00
Bus Station 2.0 0.000000 0.000000 0.00 0.0000 0.000 0.0000 0.00
Checked Baggage 2759.0 0.000000 0.000000 0.00 0.0000 0.000 0.0000 0.00
Checkpoint 903.0 0.000000 0.000000 0.00 0.0000 0.000 0.0000 0.00
Motor Vehicle 28.0 0.000000 0.000000 0.00 0.0000 0.000 0.0000 0.00
Other 11.0 0.000000 0.000000 0.00 0.0000 0.000 0.0000 0.00
Approve in Full Checked Baggage 1162.0 113.868072 192.166683 1.25 25.6600 60.075 125.9825 2200.00
Checkpoint 493.0 236.643367 404.707047 8.95 60.0000 124.000 250.1400 6183.36
Motor Vehicle 9.0 1591.428889 1459.368190 493.80 630.0000 930.180 1755.9800 5158.05
Other 4.0 398.967500 358.710134 61.11 207.2775 317.385 509.0750 899.99
Deny - 4.0 0.000000 0.000000 0.00 0.0000 0.000 0.0000 0.00
Checked Baggage 2333.0 0.000000 0.000000 0.00 0.0000 0.000 0.0000 0.00
Checkpoint 407.0 0.000000 0.000000 0.00 0.0000 0.000 0.0000 0.00
Motor Vehicle 1.0 0.000000 NaN 0.00 0.0000 0.000 0.0000 0.00
Other 13.0 0.000000 0.000000 0.00 0.0000 0.000 0.0000 0.00
Settle Checked Baggage 432.0 286.271968 339.487254 7.25 77.0700 179.995 361.5700 2500.00
Checkpoint 254.0 487.173031 1620.156849 6.00 166.9250 281.000 496.3925 25483.44
Motor Vehicle 6.0 4404.910000 7680.169379 244.00 841.8125 1581.780 2215.5025 20000.00
Плотирование
Хотя агрегаты по группам данных - один из лучших способов получить представление, визуализация данных позволяет вычленить закономерности на странице и проста для тех, кто не так хорошо знаком с агрегатными значениями. Правильно отформатированные визуализации очень важны для передачи смысла данных, и приятно видеть, что в Pandas есть некоторые из этих функций:
>>> df.plot(x='Incident Date', y='Close Amount')
>>> plt.show()
Дата инцидента по сумме закрытия
Экспорт преобразованных данных
Наконец, нам может понадобиться зафиксировать либо наши исходные данные, либо агрегаты в виде DataFrame в формате файла, отличном от того, с которого мы начали, поскольку Pandas не ограничивает вас в записи обратно в тот же формат файла.
Наиболее распространенным плоским файлом для записи в Pandas будет .csv. Судя по визуализации, похоже, что стоимость претензий TSA, хотя иногда и очень высокая из-за некоторых выбросов, в 2015 году улучшилась. Возможно, нам следует рекомендовать сравнить кадровые и процедурные изменения, чтобы продолжить движение в этом направлении, и более детально изучить, почему у нас больше инцидентов в определенное время суток.
Как и для загрузки данных, Pandas предлагает несколько методов записи данных в файл в различных форматах. Запись в файл Excel немного сложнее, чем другие, поэтому давайте запишем в еще более переносимый формат: CSV. Чтобы записать преобразованный набор данных в новый файл CSV:
>>> df.to_csv(path_or_buf='claims-2014.v1.csv')
Финальные заметки
Здесь мы увидели интересный и мощный рабочий процесс. Мы совершили круговой путь от правительственного excel-файла до Python, через довольно мощную визуализацию данных и обратно к .csv-файлу, который может быть более универсальным - и все это благодаря возможностям Pandas. Далее мы рассмотрели три центральных объекта Pandas - DataFrames, Series и dtypes
. И самое главное, мы получили более глубокое понимание интересного, реального набора данных.
Это основные понятия, которые необходимо понимать при работе с Pandas, и теперь вы можете задавать интеллектуальные вопросы (себе или Google) об этих различных объектах. Этот пример использования данных TSA показал нам, для чего именно подходит Pandas: исследование, анализ и агрегирование данных для получения выводов.
Анализ и исследование данных важны практически в любой области, но они особенно полезны для Data Scientists и специалистов по искусственному интеллекту, которым может потребоваться дробление и очистка данных очень специфическими, мелкозернистыми способами, например, получение скользящих средних на биржевых тиках. Кроме того, некоторые задачи могут нуждаться в автоматизации, а это может оказаться сложным или дорогостоящим в таких разросшихся приложениях, как Excel или Google Sheets, которые не могут предложить всю функциональность Pandas с полной мощью Python.
Представьте себе, что вы говорите бизнес-администратору, что, возможно, ему больше никогда не придется запускать этот сломанный макрос электронной таблицы! Как только анализ автоматизирован, его можно развернуть как сервис или применить к сотням тысяч записей, поступающих из базы данных. Кроме того, Pandas можно использовать для принятия важных решений после установления статистических ассоциаций между шаблонами, как это происходит каждый день.
Далее не забудьте ознакомиться с обширными библиотеками баз данных Python (например, SQLalchemy) или API-клиентами (например, Google Sheets/Slides Python Client или Airtable API для представления результатов экспертам в области). Возможности безграничны, и они только расширяются благодаря развитым библиотекам Python и активному сообществу.
Вернуться на верх