DataFrame.pivot()
и DataFrame.pivot_table()
;pandas.pivot()
и метод DataFrame.pivot()
- сводная таблица без агрегации;pandas.pivot_table()
и метод DataFrame.pivot_table()
- сводная таблица в стиле Excel;DataFrame.pivot()
и DataFrame.pivot_table()
DataFrame.pivot()
Заметка.
DataFrame.pivot()
может обрабатывать только уникальные строки, указанные индексом и столбцами. Если данные содержат дубликаты, то нужно использоватьDataFrame.pivot_table()
.
Данные часто хранятся в так называемом "stacked" или "record" формате. В "record" формате обычно имеется одна строка для каждого объекта. В формате "stacked" (например log-файл сервера) для каждого объекта, где это применимо, имеется несколько строк.
>>> import pandas as pd data = { "value": range(12), "variable": ["A"] * 3 + ["B"] * 3 + ["C"] * 3 + ["D"] * 3, "date": pd.to_datetime(["2020-01-03", "2020-01-04", "2020-01-05"] * 4) } >>> df = pd.DataFrame(data)
Для выполнения операций с временными рядами с каждой уникальной переменной лучшим представлением было бы, где columns
являются уникальными переменными, а index
даты идентифицирует отдельные наблюдения. Чтобы придать данным такую форму, используем метод DataFrame.pivot()
(также реализованный в виде функции верхнего уровня pandas.pivot()
):
>>> pivoted = df.pivot(index="date", columns="variable", values="value") >>> pivoted # variable A B C D # date # 2020-01-03 0 3 6 9 # 2020-01-04 1 4 7 10 # 2020-01-05 2 5 8 11
Если аргумент values
опущен, а входной DataFrame
имеет более одного столбца значений, которые не используются в качестве входных данных для columns
или index
в DataFrame.pivot()
, то результирующий "сводный" DataFrame
будет иметь иерархические столбцы, самый верхний уровень которых указывает на соответствующий столбец значений:
>>> df["value2"] = df["value"] * 2 >>> pivoted = df.pivot(index="date", columns="variable") >>> pivoted # value value2 # variable A B C D A B C D # date # 2020-01-03 0 3 6 9 0 6 12 18 # 2020-01-04 1 4 7 10 2 8 14 20 # 2020-01-05 2 5 8 11 4 10 16 22
Затем можно выбрать подмножества из сводного DataFrame
:
>>> pivoted["value2"] # variable A B C D # date # 2020-01-03 0 6 12 18 # 2020-01-04 2 8 14 20 # 2020-01-05 4 10 16 22
Обратите внимание, что возвращается представление базовых данных в случае, когда данные однородно типизированы.
DataFrame.pivot_table()
В то время как DataFrame.pivot()
обеспечивает сведение общего назначения с различными типами данных, библиотека pandas
также предоставляет метод DataFrame.pivot_table()
и функцию верхнего уровня pandas.pivot_table()
для сводной таблицы с агрегированием числовых данных.
Метод DataFrame.pivot_table()
можно использовать для создания сводных таблиц в стиле электронных таблиц Excel.
>>> import datetime >>> import numpy as np df = pd.DataFrame( { "A": ["one", "one", "two", "three"] * 6, "B": ["A", "B", "C"] * 8, "C": ["foo", "foo", "foo", "bar", "bar", "bar"] * 4, "D": np.random.randn(24), "E": np.random.randn(24), "F": [datetime.datetime(2013, i, 1) for i in range(1, 13)] + [datetime.datetime(2013, i, 15) for i in range(1, 13)], } ) >>> df # A B C D E F # 0 one A foo -2.462103 -0.339259 2013-01-01 # 1 one B foo -2.246244 1.581998 2013-02-01 # 2 two C foo 1.460594 0.775635 2013-03-01 # 3 three A bar -0.634787 1.243068 2013-04-01 # ... # 20 one C foo -0.388582 0.695563 2013-09-15 # 21 one A bar -1.047349 0.287958 2013-10-15 # 22 two B bar -0.354933 1.664564 2013-11-15 # 23 three C bar 2.073142 -0.195454 2013-12-15 # # [24 rows x 6 columns]
>>> pd.pivot_table(df, values="D", index=["A", "B"], columns=["C"]) # C bar foo # A B # one A -0.938132 -0.361404 # B 1.011535 -1.257616 # C 0.001240 0.078341 # three A -0.155351 NaN # B NaN -0.093591 # C 0.684645 NaN # two A NaN -0.731589 # B -0.588690 NaN # C NaN 0.753767
>>> pd.pivot_table(df, values=["D", "E"], index=["B"], columns=["A", "C"], aggfunc="sum") # D ... E # A one three ... three two # C bar foo bar foo ... bar foo bar foo # B ... # A -1.876265 -0.722809 -0.310703 NaN ... 1.041608 NaN NaN -0.719820 # B 2.023070 -2.515232 NaN -0.187183 ... NaN 1.484646 2.053085 NaN # C 0.002481 0.156682 1.369290 NaN ... -0.410849 NaN NaN -1.195039 # # [3 rows x 12 columns]
>>> pd.pivot_table(df, values="E", index=["B", "C"], columns=["A"], aggfunc=["sum", "mean"]) # sum mean # A one three two one three two # B C # A bar 1.200118 1.041608 NaN 0.600059 0.520804 NaN # foo 2.002847 NaN -0.719820 1.001423 NaN -0.359910 # B bar -0.363976 NaN 2.053085 -0.181988 NaN 1.026543 # foo 0.738202 1.484646 NaN 0.369101 0.742323 NaN # C bar -1.391516 -0.410849 NaN -0.695758 -0.205425 NaN # foo 1.025271 NaN -1.195039 0.512636 NaN -0.597519
В результате DataFrame
может иметь MultiIndex
в индексе или столбце. Если имя столбца в values
не указано, то сводная таблица будет включать все данные на дополнительном уровне иерархии в столбцах
>>> pd.pivot_table(df[["A", "B", "C", "D", "E"]], index=["A", "B"], columns=["C"]) # D E # C bar foo bar foo # A B # one A -0.938132 -0.361404 0.600059 1.001423 # B 1.011535 -1.257616 -0.181988 0.369101 # C 0.001240 0.078341 -0.695758 0.512636 # three A -0.155351 NaN 0.520804 NaN # B NaN -0.093591 NaN 0.742323 # C 0.684645 NaN -0.205425 NaN # two A NaN -0.731589 NaN -0.359910 # B -0.588690 NaN 1.026543 NaN # C NaN 0.753767 NaN -0.597519
Кроме того, можно использовать pandas.Grouper()
для ключевых аргументов index
и columns
.
>>> pd.pivot_table(df, values="D", index=pd.Grouper(freq="M", key="F"), columns="C") # C bar foo # F # 2013-01-31 NaN -0.361404 # 2013-02-28 NaN -1.257616 # 2013-03-31 NaN 0.753767 # 2013-04-30 -0.155351 NaN # 2013-05-31 1.011535 NaN # 2013-06-30 0.001240 NaN # 2013-07-31 NaN -0.731589 # 2013-08-31 NaN -0.093591 # 2013-09-30 NaN 0.078341 # 2013-10-31 -0.938132 NaN # 2013-11-30 -0.588690 NaN # 2013-12-31 0.684645 NaN
df = pd.DataFrame( data={ "Province": ["ON", "QC", "BC", "AL", "AL", "MN", "ON"], "City": [ "Toronto", "Montreal", "Vancouver", "Calgary", "Edmonton", "Winnipeg", "Windsor", ], "Sales": [13, 6, 16, 8, 4, 3, 1], } ) >>> df # Province City Sales # 0 ON Toronto 13 # 1 QC Montreal 6 # 2 BC Vancouver 16 # 3 AL Calgary 8 # 4 AL Edmonton 4 # 5 MN Winnipeg 3 # 6 ON Windsor 1
table = df.pivot_table( values=["Sales"], index=["Province"], columns=["City"], aggfunc="sum", margins=True, ) >>> table.stack("City", future_stack=True) # Sales # Province City # AL Calgary 8.0 # Edmonton 4.0 # Montreal NaN # Toronto NaN # Vancouver NaN # ... ... # All Toronto 13.0 # Vancouver 16.0 # Windsor 1.0 # Winnipeg 3.0 # All 51.0 # # [48 rows x 1 columns]
DataFrame
с годовыми даннымиЧтобы создать перекрестную таблицу по годам и месяцам, необходимо выполнить следующие действия.
df = pd.DataFrame( {"value": np.random.randn(36)}, index=pd.date_range("2011-01-01", freq="M", periods=36), ) >>> df.pivot_table( ... index=df.index.month, columns=df.index.year, values="value", aggfunc="sum" ... ) # 2011 2012 2013 # 1 -0.684229 0.407663 0.415221 # 2 0.590280 0.417917 -0.164821 # 3 -0.737578 0.406965 -1.893850 # 4 0.951886 1.272036 1.654187 # 5 0.123040 -1.425201 -0.258822 # 6 -1.501977 1.208778 0.782863 # 7 -1.087257 -0.411236 -0.135623 # 8 -0.326061 -0.935996 -0.945246 # 9 0.083486 0.930429 0.998789 # 10 -0.568210 -0.973238 -1.432825 # 11 -1.685772 0.457168 -0.411864 # 12 -1.345183 -1.696976 -1.095169
pandas.pivot(data, *, columns, index=no_default, values=no_default)
:Pandas предоставляет эквивалентный метод
DataFrame.pivot()
, который принимает аналогичные аргументы за исключением аргументаdata
, т.к. сам является вызывающим (исходным)DataFrame
.
Функция pandas.pivot()
и метод DataFrame.pivot()
изменяет форму данных (создание сводной таблицы) на основе значений столбцов. Использует уникальные значения из указанного индекса/столбцов для формирования осей результирующего DataFrame
. Возвращает измененный DataFrame
, организованный по заданным значениям индекса/столбца.
Эта функция не поддерживает агрегацию данных, несколько значений приведут к созданию MultiIndex
в столбцах. Если необходимо использовать функции агрегирования данных, то нужно использовать функцию pandas.pivot_table()
или метод DataFrame.pivot_table()
.
Поднимает исключение ValueError
если есть любые комбинации индексов, столбцов с несколькими значениями.
Заметка.
DataFrame.pivot()
может обрабатывать только уникальные строки, указанные индексом и столбцами. Если данные содержат дубликаты, то нужно использоватьDataFrame.pivot_table()
.
pandas.pivot()
:data
- исходный DataFrame
;columns
- столбец, используемый для создания столбцов нового DataFrame
. Принимает: строку или список строк.index=no_default
- столбец, используемый для создания индекса нового DataFrame
. Если не указано, то будет использоваться существующий индекс. Принимает строку или список строк.values=no_default
- столбцы, используемые для заполнения значений нового DataFrame
. Если не указано, то будут использованы все оставшиеся столбцы, а результат будет иметь иерархически индексированные столбцы. Принимает: строку или список строк.pandas.pivot()
>>> import pandas as pd df = pd.DataFrame({'foo': ['one', 'one', 'one', 'two', 'two', 'two'], 'bar': ['A', 'B', 'C', 'A', 'B', 'C'], 'baz': [1, 2, 3, 4, 5, 6], 'zoo': ['x', 'y', 'z', 'q', 'w', 't']}) >>> df # foo bar baz zoo # 0 one A 1 x # 1 one B 2 y # 2 one C 3 z # 3 two A 4 q # 4 two B 5 w # 5 two C 6 t
>>> df.pivot(index='foo', columns='bar', values='baz') # bar A B C # foo # one 1 2 3 # two 4 5 6
>>> df.pivot(index='foo', columns='bar')['baz'] # bar A B C # foo # one 1 2 3 # two 4 5 6
>>> df.pivot(index='foo', columns='bar', values=['baz', 'zoo']) # baz zoo # bar A B C A B C # foo # one 1 2 3 x y z # two 4 5 6 q w t
Можно назначить список имен столбцов или список имен индексов.
df = pd.DataFrame({ "lev1": [1, 1, 1, 2, 2, 2], "lev2": [1, 1, 2, 1, 1, 2], "lev3": [1, 2, 1, 2, 1, 2], "lev4": [1, 2, 3, 4, 5, 6], "values": [0, 1, 2, 3, 4, 5]}) >>>df # lev1 lev2 lev3 lev4 values # 0 1 1 1 1 0 # 1 1 1 2 2 1 # 2 1 2 1 3 2 # 3 2 1 2 4 3 # 4 2 1 1 5 4 # 5 2 2 2 6 5
>>> df.pivot(index="lev1", columns=["lev2", "lev3"], values="values") # lev2 1 2 # lev3 1 2 1 2 # lev1 # 1 0.0 1.0 2.0 NaN # 2 4.0 3.0 NaN 5.0
>>> df.pivot(index=["lev1", "lev2"], columns=["lev3"], values="values") # lev3 1 2 # lev1 lev2 # 1 1 0.0 1.0 # 2 2.0 NaN # 2 1 4.0 3.0 # 2 NaN 5.0
Если есть дубликаты - возникает исключение ValueError
.
df = pd.DataFrame({"foo": ['one', 'one', 'two', 'two'], "bar": ['A', 'A', 'B', 'C'], "baz": [1, 2, 3, 4]}) >>> df # foo bar baz # 0 one A 1 # 1 one A 2 # 2 two B 3 # 3 two C 4
Обратите внимание, что первые две строки для аргумента index
и columns
одинаковы.
>>> df.pivot(index='foo', columns='bar', values='baz') # Traceback (most recent call last): # ... # ValueError: Index contains duplicate entries, cannot reshape
pandas.pivot_table(data, values=None, index=None, columns=None, aggfunc='mean', fill_value=None, margins=False, dropna=True, margins_name='All', observed=False, sort=True)
:Pandas предоставляет эквивалентный метод
DataFrame.pivot_table()
, который принимает аналогичные аргументы за исключениемdata
, т.к. сам является вызывающим (исходным)DataFrame
.
Функция pandas.pivot_table()
и метод DataFrame.pivot_table()
создает сводную таблицу в стиле электронной таблицы Excel в виде DataFrame
.
Уровни в сводной таблице будут храниться в объектах MultiIndex
(иерархических индексах) индексе и столбцах результирующего DataFrame
.
Принимаемые аргументы pivot_table()
:
data
- исходный DataFrame
;
values=None
- столбец или столбцы для агрегирования. Принимает скалярное значение или список значений.
index=None
- ключи для группировки по индексу сводной таблицы. Если передается список, он может содержать любой из принимаемых типов (кроме списка). Если передается массив, он должен быть той же длины, что и данные, и будет использоваться тем же образом, что и значения столбцов. Принимает: строку с меткой столбца, pandas.Grouper()
, массив или список этих типов.
columns=None
- ключи для группировки по столбцу сводной таблицы. Если передается список, он может содержать любой из принимаемых типов (кроме списка). Если передается массив, он должен быть той же длины, что и данные, и будет использоваться тем же образом, что и значения столбцов. Принимает: строку с меткой столбца, pandas.Grouper()
, массив или список этих типов.
aggfunc='mean'
- если передается список агрегирующих функций, то результирующая сводная таблица будет иметь иерархические столбцы, верхним уровнем которых являются имена функций. Если передается словарь dict
, то ключом для агрегирования является столбец, а значением - агрегирующая функция или их список. Если margins=True
, то aggfunc
будет использоваться для вычисления частичных агрегированных значений. Принимает: строку с именем функции, список имен функции, словарь dict
.
fill_value=None
- значение для замены отсутствующих значений (в результирующей сводной таблице, после агрегирования).
margins=False
- если margins=True
, то в строках и столбцах будут добавлены специальные столбцы и строки All
(смотри аргумент margins_name
) с частичными групповыми статистическими выражениями по категориям.
dropna=True
- не включает столбцы, все записи которых имеют значение NaN
. Если задано значение True
, то перед вычислением полей, строки со значением NaN
в любом столбце будут опущены.
margins_name='All'
- имя строки/столбца, которое будет содержать итоги при margins=True
.
observed=False
- применимо только в том случае, если кто-либо из Grouper
является Categoricals
.
True
: отображает наблюдаемые значения только для категориальных Grouper
. Grouper
.sort=True
- следует ли сортировать результат.
pandas.pivot_table()
>>> import pandas as pd df = pd.DataFrame({"A": ["foo", "foo", "foo", "foo", "foo", "bar", "bar", "bar", "bar"], "B": ["one", "one", "one", "two", "two", "one", "one", "two", "two"], "C": ["small", "large", "large", "small", "small", "large", "small", "small", "large"], "D": [1, 2, 2, 3, 3, 4, 5, 6, 7], "E": [2, 4, 5, 5, 6, 6, 8, 9, 9]}) >>> df # A B C D E # 0 foo one small 1 2 # 1 foo one large 2 4 # 2 foo one large 2 5 # 3 foo two small 3 5 # 4 foo two small 3 6 # 5 bar one large 4 6 # 6 bar one small 5 8 # 7 bar two small 6 9 # 8 bar two large 7 9
В этом первом примере значения агрегируются путем получения суммы.
>>> table = pd.pivot_table(df, values='D', index=['A', 'B'], ... columns=['C'], aggfunc="sum") >>> table # C large small # A B # bar one 4.0 5.0 # two 7.0 6.0 # foo one 4.0 1.0 # two NaN 6.0
Можно заполнить недостающие значения, используя аргумент fill_value
.
>>> table = pd.pivot_table(df, values='D', index=['A', 'B'], ... columns=['C'], aggfunc="sum", fill_value=0) >>> table # C large small # A B # bar one 4 5 # two 7 6 # foo one 4 1 # two 0 6
В следующем примере выполняется агрегирование путем получения среднего значения по нескольким столбцам.
>>> table = pd.pivot_table(df, values=['D', 'E'], index=['A', 'C'], ... aggfunc={'D': "mean", 'E': "mean"}) >>> table # D E # A C # bar large 5.500000 7.500000 # small 5.500000 8.500000 # foo large 2.000000 4.500000 # small 2.333333 4.333333
Также можно рассчитать несколько типов агрегированных значений для любого заданного столбца значений.
>>> table = pd.pivot_table(df, values=['D', 'E'], index=['A', 'C'], ... aggfunc={'D': "mean", ... 'E': ["min", "max", "mean"]}) >>> table # D E # mean max mean min # A C # bar large 5.500000 9 7.500000 6 # small 5.500000 9 8.500000 8 # foo large 2.000000 5 4.500000 4 # small 2.333333 6 4.333333 2