Как использовать Pandas GroupBy, счетчики и счетчики значений

Оглавление

Если вы занимаетесь изучением данных, вы, вероятно, тратите много времени на очистку и манипулирование данными для использования в своих приложениях. Одной из основных библиотек для подготовки данных является библиотека Pandas для Python.

В предыдущей статье мы рассмотрели историю Pandas и базовое использование Pandas DataFrame, основной структуры данных в Pandas. Ознакомьтесь с этой статьей, если хотите поближе познакомиться с основами Pandas.

В этой заметке мы рассмотрим несколько основных методов Pandas DataFrames. Эти методы помогут вам сегментировать и просматривать ваши DataFrames во время анализа.

Мы покроем

  • Использование Pandas groupby для сегментирования вашего DataFrame на группы.
  • Исследование вашего Pandas DataFrame с помощью counts и value_counts.

Давайте начнем.

Панды groupby

Pandas обычно используется для изучения и организации больших объемов табличных данных, подобно супермощной электронной таблице Excel. Часто возникает необходимость организовать pandas DataFrame в подгруппы для дальнейшего анализа.

Например, возможно, у вас есть данные биржевого тикера в DataFrame, как мы рассматривали в предыдущем сообщении. Ваш Pandas DataFrame может выглядеть следующим образом:

>>> df
          date symbol     open     high      low    close    volume
0   2019-03-01   AMZN  1655.13  1674.26  1651.00  1671.73   4974877
1   2019-03-04   AMZN  1685.00  1709.43  1674.36  1696.17   6167358
2   2019-03-05   AMZN  1702.95  1707.80  1689.01  1692.43   3681522
3   2019-03-06   AMZN  1695.97  1697.75  1668.28  1668.95   3996001
4   2019-03-07   AMZN  1667.37  1669.75  1620.51  1625.95   4957017
5   2019-03-01   AAPL   174.28   175.15   172.89   174.97  25886167
6   2019-03-04   AAPL   175.69   177.75   173.97   175.85  27436203
7   2019-03-05   AAPL   175.94   176.00   174.54   175.53  19737419
8   2019-03-06   AAPL   174.67   175.49   173.94   174.52  20810384
9   2019-03-07   AAPL   173.87   174.44   172.02   172.50  24796374
10  2019-03-01   GOOG  1124.90  1142.97  1124.75  1140.99   1450316
11  2019-03-04   GOOG  1146.99  1158.28  1130.69  1147.80   1446047
12  2019-03-05   GOOG  1150.06  1169.61  1146.19  1162.03   1443174
13  2019-03-06   GOOG  1162.49  1167.57  1155.49  1157.86   1099289
14  2019-03-07   GOOG  1155.72  1156.76  1134.91  1143.30   1166559

Возможно, мы хотим проанализировать информацию об этих акциях по каждому символу, а не объединять данные Amazon ("AMZN") с данными Google ("GOOG") или Apple ("AAPL").

Здесь полезен метод Pandas groupby. Вы можете использовать groupby для разбивки данных на подмножества для дальнейшего анализа.

Базовые панды groupby использование

Давайте сделаем несколько базовых примеров использования groupby, чтобы увидеть, как это полезно.

В вашем интерпретаторе Python введите следующие команды:

>>> import pandas as pd
>>> import numpy as np
>>> url = 'https://gist.githubusercontent.com/alexdebrie/b3f40efc3dd7664df5a20f5eee85e854/raw/ee3e6feccba2464cbbc2e185fb17961c53d2a7f5/stocks.csv'
>>> df = pd.read_csv(url)
>>> df
          date symbol     open     high      low    close    volume
0   2019-03-01   AMZN  1655.13  1674.26  1651.00  1671.73   4974877
1   2019-03-04   AMZN  1685.00  1709.43  1674.36  1696.17   6167358
2   2019-03-05   AMZN  1702.95  1707.80  1689.01  1692.43   3681522
3   2019-03-06   AMZN  1695.97  1697.75  1668.28  1668.95   3996001
4   2019-03-07   AMZN  1667.37  1669.75  1620.51  1625.95   4957017
5   2019-03-01   AAPL   174.28   175.15   172.89   174.97  25886167
6   2019-03-04   AAPL   175.69   177.75   173.97   175.85  27436203
7   2019-03-05   AAPL   175.94   176.00   174.54   175.53  19737419
8   2019-03-06   AAPL   174.67   175.49   173.94   174.52  20810384
9   2019-03-07   AAPL   173.87   174.44   172.02   172.50  24796374
10  2019-03-01   GOOG  1124.90  1142.97  1124.75  1140.99   1450316
11  2019-03-04   GOOG  1146.99  1158.28  1130.69  1147.80   1446047
12  2019-03-05   GOOG  1150.06  1169.61  1146.19  1162.03   1443174
13  2019-03-06   GOOG  1162.49  1167.57  1155.49  1157.86   1099289
14  2019-03-07   GOOG  1155.72  1156.76  1134.91  1143.30   1166559

В описанных выше шагах мы импортируем библиотеки Pandas и NumPy, затем создаем базовый DataFrame, загружая CSV-данные с URL. Мы выводим наш DataFrame на консоль, чтобы посмотреть, что мы имеем.

Теперь давайте сгруппируем наш DataFrame по символу акции. Самый простой и распространенный способ использования groupby - это передача одного или нескольких имен столбцов. В нашем примере мы будем использовать "символ" в качестве имени столбца для группировки:

>>> symbols = df.groupby('symbol')
>>> print(symbols.groups)
{'AAPL': Int64Index([5, 6, 7, 8, 9], dtype='int64'),
 'AMZN': Int64Index([0, 1, 2, 3, 4], dtype='int64'),
 'GOOG': Int64Index([10, 11, 12, 13, 14], dtype='int64')}

Интерпретация вывода печатных групп может быть немного сложной для понимания. В приведенном выше выводе показано, что у нас есть три группы: AAPL, AMZN и GOOG. Для каждой группы он включает индекс строк исходного DataFrame, которые принадлежат каждой группе.

Ввод в groupby является достаточно гибким. Вы можете выбрать группировку по нескольким столбцам. Например, если бы у нас был столбец год, мы могли бы сгруппировать по символу акции и году, чтобы выполнить анализ данных по акциям за год.

Использование пользовательской функции в Pandas groupby

В предыдущем примере мы передали имя столбца в метод groupby. Вы также можете передать свою собственную функцию методу groupby. Эта функция получит номер индекса для каждой строки в DataFrame и должна вернуть значение, которое будет использоваться для группировки. Это может обеспечить значительную гибкость при группировке строк с использованием сложной логики.

В качестве примера, представьте, что мы хотим сгруппировать наши строки в зависимости от того, выросла ли цена акции в этот конкретный день. Мы бы использовали следующее:

>>> def increased(idx):
...     return df.loc[idx].close > df.loc[idx].open
...
>>> df.groupby(increased).groups
{False: Int64Index([2, 3, 4, 7, 8, 9, 13, 14], dtype='int64'),
 True: Int64Index([0, 1, 5, 6, 10, 11, 12], dtype='int64')}

Сначала мы определим функцию increased, которая получает индекс. Она возвращает True, если значение close для этой строки в DataFrame больше значения open; в противном случае она возвращает False.

Когда мы передаем эту функцию в метод groupby(), наш DataFrame группируется на две группы в зависимости от того, была ли цена закрытия акции выше цены открытия в данный день.

Операция над группами Pandas

После создания групп с помощью функции groupby вы можете выполнить некоторые удобные манипуляции с данными в полученных группах.

В нашем примере выше мы создали группы наших биржевых тикеров по символам. Давайте теперь найдем средний объем торгов для каждого символа.

>>> symbols['volume'].agg(np.mean)
symbol
AAPL    23733309.4
AMZN     4755355.0
GOOG     1321077.0
Name: volume, dtype: float64

Для выполнения этой задачи вы указываете столбец, над которым хотите оперировать-volume, затем используете метод agg Пандаса для применения функции среднего значения NumPy. Результатом является средний объем для каждого из трех символов. Из него видно, что объем торгов AAPL на порядок больше, чем объем торгов AMZN и GOOG.

Итерация и выбор групп

Итерация является основным шаблоном программирования, и немногие языки имеют более приятный синтаксис для итерации, чем Python. Встроенные в Python средства понимания списков и генераторы делают итерацию простым делом.

Pandas groupby ничем не отличается, поскольку обеспечивает отличную поддержку итерации. Вы можете обращаться к объекту результата groupby с помощью цикла for:

>>> for symbol, group in symbols:
...     print(symbol)
...     print(group)
...
AAPL
         date symbol    open    high     low   close    volume
5  2019-03-01   AAPL  174.28  175.15  172.89  174.97  25886167
6  2019-03-04   AAPL  175.69  177.75  173.97  175.85  27436203
7  2019-03-05   AAPL  175.94  176.00  174.54  175.53  19737419
8  2019-03-06   AAPL  174.67  175.49  173.94  174.52  20810384
9  2019-03-07   AAPL  173.87  174.44  172.02  172.50  24796374
AMZN
         date symbol     open     high      low    close   volume
0  2019-03-01   AMZN  1655.13  1674.26  1651.00  1671.73  4974877
1  2019-03-04   AMZN  1685.00  1709.43  1674.36  1696.17  6167358
2  2019-03-05   AMZN  1702.95  1707.80  1689.01  1692.43  3681522
3  2019-03-06   AMZN  1695.97  1697.75  1668.28  1668.95  3996001
4  2019-03-07   AMZN  1667.37  1669.75  1620.51  1625.95  4957017
GOOG
          date symbol     open     high      low    close   volume
10  2019-03-01   GOOG  1124.90  1142.97  1124.75  1140.99  1450316
11  2019-03-04   GOOG  1146.99  1158.28  1130.69  1147.80  1446047
12  2019-03-05   GOOG  1150.06  1169.61  1146.19  1162.03  1443174
13  2019-03-06   GOOG  1162.49  1167.57  1155.49  1157.86  1099289
14  2019-03-07   GOOG  1155.72  1156.76  1134.91  1143.30  1166559

Каждая итерация объекта groupby возвращает два значения. Первое значение - это идентификатор группы, который является значением для столбца(ов), по которому они были сгруппированы. Второе значение - это сама группа, которая представляет собой объект Pandas DataFrame.

Метод Пандаса get_group

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

>>> aapl = symbols.get_group('AAPL')
>>> aapl
         date symbol    open    high     low   close    volume
5  2019-03-01   AAPL  174.28  175.15  172.89  174.97  25886167
6  2019-03-04   AAPL  175.69  177.75  173.97  175.85  27436203
7  2019-03-05   AAPL  175.94  176.00  174.54  175.53  19737419
8  2019-03-06   AAPL  174.67  175.49  173.94  174.52  20810384
9  2019-03-07   AAPL  173.87  174.44  172.02  172.50  24796374
>>> type(aapl)
<class 'pandas.core.frame.DataFrame'>

В приведенном выше примере мы используем метод Pandas get_group для получения всех строк AAPL. Чтобы получить определенную группу, вы передаете идентификатор группы в метод get_group. Этот метод возвращает Pandas DataFrame, которым мы можем манипулировать по мере необходимости.

Понимание формы данных с помощью Pandas count и value_counts

Если вы работаете с большим DataFrame, вам потребуется использовать различные эвристики для понимания формы ваших данных. В этом разделе мы рассмотрим Pandas count и value_counts, два метода оценки вашего DataFrame.

Метод count покажет вам количество значений для каждого столбца в вашем DataFrame. Используя наш DataFrame, мы получим следующий результат:

>>> df.count()
date      15
symbol    15
open      15
high      15
low       15
close     15
volume    15
dtype: int64

Вывод не особенно полезен для нас, поскольку каждая из наших 15 строк имеет значение для каждого столбца. Однако это может быть очень полезно, если в вашем наборе данных отсутствует большое количество значений. Использование метода подсчета может помочь выявить неполные столбцы. После этого вы можете решить, исключить ли эти столбцы из обработки или предоставить значения по умолчанию, если это необходимо.

Панды value_counts метод

Для нашего случая более полезен метод value_counts. Этот метод вернет количество уникальных значений для конкретного столбца. Если у вас есть непрерывные переменные, как наши столбцы, вы можете предоставить дополнительный аргумент "bins", чтобы разделить значения на полуоткрытые бины.

Давайте воспользуемся методом Pandas value_counts для просмотра формы нашего volume столбца.

>>> df['volume'].value_counts(bins=4)
(1072952.085, 7683517.5]    10
(20851974.5, 27436203.0]     3
(14267746.0, 20851974.5]     2
(7683517.5, 14267746.0]      0
Name: volume, dtype: int64

В приведенном выше выводе Pandas создал четыре отдельных бина для нашего столбца объема и показал нам количество строк, попавших в каждый бином.

И counts(), и value_counts() являются отличными утилитами для быстрого понимания формы ваших данных.

Заключение

В этом посте мы познакомились с groupby, count и value_counts - тремя основными методами в Pandas.

Pandas - это мощный инструмент для манипулирования данными, если вы знаете основные операции и как его использовать. 

Вернуться на верх