6.24. DataFrame Pivot

  • pd.pivot_table()

  • Create a spreadsheet-style pivot table as a DataFrame

  • Levels in the pivot table will be stored in MultiIndex objects

Create a spreadsheet-style pivot table as a DataFrame. The levels in the pivot table will be stored in MultiIndex objects (hierarchical indexes) on the index and columns of the result DataFrame.

6.24.1. Parameters

values : column to aggregate, optional

indexcolumn, Grouper, array, or list of the previous

If an array is passed, it must be the same length as the data. The list can contain any of the other types (except list). Keys to group by on the pivot table index. If an array is passed, it is being used as the same manner as column values.

columnscolumn, Grouper, array, or list of the previous

If an array is passed, it must be the same length as the data. The list can contain any of the other types (except list). Keys to group by on the pivot table column. If an array is passed, it is being used as the same manner as column values.

aggfuncfunction, list of functions, dict, default numpy.mean

If list of functions passed, the resulting pivot table will have hierarchical columns whose top level are the function names (inferred from the function objects themselves) If dict is passed, the key is column to aggregate and value is function or list of functions.

fill_valuescalar, default None

Value to replace missing values with (in the resulting pivot table, after aggregation).

marginsbool, default False

Add all row / columns (e.g. for subtotal / grand totals).

dropnabool, default True

Do not include columns whose entries are all NaN.

margins_namestr, default 'All'

Name of the row / column that will contain the totals when margins is True.

observedbool, default False

This only applies if any of the groupers are Categoricals. If True: only show observed values for categorical groupers. If False: show all values for categorical groupers.

sortbool, default True

Specifies if the result should be sorted.

6.24.2. Returns

DataFrame

An Excel style pivot table.

6.24.3. See Also

DataFrame.pivot

Pivot without aggregation that can handle non-numeric data.

DataFrame.melt

Unpivot a DataFrame from wide to long format, optionally leaving identifiers set.

wide_to_long

Wide panel to long format. Less flexible but more user-friendly than melt.

6.24.4. SetUp

>>> import pandas as pd
>>>
>>>
>>> df = pd.DataFrame([
...     {'firstname': 'Alice', 'lastname': 'Apricot', 'age': 30, 'gender': 'female'},
...     {'firstname': 'Bob', 'lastname': 'Blackthorn', 'age': 31, 'gender': 'male'},
...     {'firstname': 'Carol', 'lastname': 'Corn', 'age': 32, 'gender': 'female'},
...     {'firstname': 'Dave', 'lastname': 'Durian', 'age': 33, 'gender': 'male'},
...     {'firstname': 'Eve', 'lastname': 'Elderberry', 'age': 34, 'gender': 'female'},
...     {'firstname': 'Mallory', 'lastname': 'Melon', 'age': 15, 'gender': 'male'},
... ], index=['a', 'b', 'c', 'd', 'e', 'm'])
>>> df
  firstname    lastname  age  gender
a     Alice     Apricot   30  female
b       Bob  Blackthorn   31    male
c     Carol        Corn   32  female
d      Dave      Durian   33    male
e       Eve  Elderberry   34  female
m   Mallory       Melon   15    male

6.24.5. Pivot Table

  • By default, the pivot_table function will compute a mean of the values

>>> df.pivot_table(
...     values='age',
...     index='gender'
... )
              age
gender
female  32.000000
male    26.333333
>>> df.pivot_table(
...     values='age',
...     index='gender',
...     aggfunc='mean'
... )
              age
gender
female  32.000000
male    26.333333
>>> df.pivot_table(
...     values='age',
...     index='gender',
...     aggfunc='median'
... )
         age
gender
female  32.0
male    31.0

6.24.6. Aggregation Function

  • You can specify the aggregation function to use with the aggfunc parameter

>>> df.pivot_table(
...     values='firstname',
...     index='gender',
...     aggfunc='count'
... )
        firstname
gender
female          3
male            3
>>> df['gender'].value_counts()
gender
female    3
male      3
Name: count, dtype: int64

6.24.7. Multiple Aggregations

  • You can specify multiple aggregation functions to use with the aggfunc parameter

>>> df.pivot_table(
...     values='age',
...     index='gender',
...     aggfunc=['mean', 'min', 'max']
... )
             mean min max
              age age age
gender
female  32.000000  30  34
male    26.333333  15  33

6.24.8. Multiple Value Columns

  • You can specify named aggregations to use with the aggfunc parameter

>>> df.pivot_table(
...     values=['age', 'firstname'],
...     index='gender',
...     aggfunc={
...         'age': 'mean',
...         'firstname': 'count'
...     }
... )
              age  firstname
gender
female  32.000000          3
male    26.333333          3
>>> df.pivot_table(
...     index='gender',
...     values=['age', 'firstname'],
...     aggfunc={
...         'age': ['mean', 'min', 'max'],
...         'firstname': 'count'
...     }
... )
       age                firstname
       max       mean min     count
gender
female  34  32.000000  30         3
male    33  26.333333  15         3

6.24.9. Margins

  • You can add margins to the pivot table with the margins parameter

Without margins:

>>> df.pivot_table(
...     index='gender',
...     values='age',
...     aggfunc='mean',
... )
              age
gender
female  32.000000
male    26.333333

With margins:

>>> df.pivot_table(
...     index='gender',
...     values='age',
...     aggfunc='mean',
...     margins=True,
... )
              age
gender
female  32.000000
male    26.333333
All     29.166667

6.24.10. Group by Multiple Columns

  • This is one of the most common pivot table layouts.

>>> df
  firstname    lastname  age  gender
a     Alice     Apricot   30  female
b       Bob  Blackthorn   31    male
c     Carol        Corn   32  female
d      Dave      Durian   33    male
e       Eve  Elderberry   34  female
m   Mallory       Melon   15    male
>>> df['adult'] = df['age'] >= 18
>>>
>>> df
  firstname    lastname  age  gender  adult
a     Alice     Apricot   30  female   True
b       Bob  Blackthorn   31    male   True
c     Carol        Corn   32  female   True
d      Dave      Durian   33    male   True
e       Eve  Elderberry   34  female   True
m   Mallory       Melon   15    male  False
>>> df.pivot_table(
...     index='gender',
...     values='age',
...     columns='adult',
...     aggfunc='count',
... )
adult   False  True
gender
female    NaN    3.0
male      1.0    2.0

6.24.11. Fill Missing Values

  • You can use multiple index levels in the pivot table.

>>> df.pivot_table(
...     index='gender',
...     values='age',
...     columns='adult',
...     aggfunc='count',
...     fill_value=0,
... )
adult   False  True
gender
female      0      3
male        1      2

6.24.12. Using Multiple Index Levels

>>> df.pivot_table(
...     index=['gender', 'adult'],
...     values='age',
...     aggfunc='mean'
... )
               age
gender adult
female True   32.0
male   False  15.0
       True   32.0

6.24.13. Several Aggregations at Once

>>> df.pivot_table(
...     index='gender',
...     values='age',
...     aggfunc=['count', 'mean', 'std']
... )
       count       mean       std
         age        age       age
gender
female     3  32.000000  2.000000
male       3  26.333333  9.865766

6.24.14. Equivalent to SQL GROUP BY

  • You can use pivot_table to perform SQL-like GROUP BY operations.

>>> df.pivot_table(
...     index='gender',
...     values='age',
...     aggfunc='mean',
... )
              age
gender
female  32.000000
male    26.333333
>>> df.groupby('gender')['age'].mean()
gender
female    32.000000
male      26.333333
Name: age, dtype: float64