龙空技术网

Python Pandas数据分析 - Day 8 - 透视表(Pivot Table)

德里克丝 171

前言:

现时朋友们对“datatablecss”大致比较关怀,各位老铁们都想要了解一些“datatablecss”的相关文章。那么小编同时在网上搜集了一些有关“datatablecss””的相关资讯,希望各位老铁们能喜欢,你们快快来学习一下吧!

前言

抱歉,最近工作上的事情多了一点,Pandas的分析学习略有耽误。今天继续补上对于透视表Pivot table的学习。

通过下面的图示,我们了解到透视表有如下特征:

透视表是一个统计指标的表,能够汇总更加广泛的数据;可以通过更多的汇总方式对数据进行聚合,如求和sum,平均average,最小min,最大max等;Pivot_table()方法能够通过DataFrame对象创建透视表;可以在列方向上指定聚合函数,默认是numpy.mean;在透视表中可以将列用作索引,类似Groupby的操作方式;

透视表定义

下面我们通过例子进行演示。

正文

pivot_table方法的语法如下:

DataFrame.pivot_table(values=None, index=None, columns=None, aggfunc='mean', fill_value=None, margins=False, dropna=True, margins_name='All', observed=False, sort=True)[source]¶

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.

其中几个参数需要注意:

index参数,相当于DataFrame中的index概念,只是将原始DataFrame中的一个维度进行了分组处理,类似Groupby概念columns参数相当与在列方向axis=1进行数据聚合操作values参数,指定了分析的指标数据如销售额,利润额aggfunc参数,指定了每个指标对应的聚合方法,如mean,sum等,且每个指标可以以列表形式指定多个计算方法fill_value = 0,此参数对于在某一个综合维度上没有的数据(NaN),转换为了0,从而可以继续参与到聚合操作中代码实现

# -*- coding: utf-8 -*-"""Created on Sun Jan 16 21:04:31 2022@author: txdmxcg@外星人学Python - Chapter 10 - Pivot Table"""# Step1: Import the Librariesimport osos.chdir("E:/2018-VGIC/21_SuccessFactor/Python Training/pandas专栏数据与源码/文章源码/文章源码/src/10/src")import pandas as pdimport numpy as np# Step2: Get your data readyg_date_cols = ['订单日期']def get_df():    return pd.read_excel(        'data/某咖啡公司销售数据.xlsx',        header = 0,        parse_dates = g_date_cols)   # parse_dates 表示哪些列作为日期进行解析df = get_df()df.info()# =============================================================================# <class 'pandas.core.frame.DataFrame'># RangeIndex: 4248 entries, 0 to 4247# Data columns (total 14 columns):#  #   Column  Non-Null Count  Dtype         # ---  ------  --------------  -----         #  0   订单日期    4248 non-null   datetime64[ns]#  1   市场类别    4248 non-null   object        #  2   区域      4248 non-null   object        #  3   产品类别    4248 non-null   object        #  4   产品名称    4248 non-null   object        #  5   预计销售成本  4248 non-null   int64         #  6   预计毛利    4248 non-null   int64         #  7   预计利润    4248 non-null   int64         #  8   预计销售额   4248 non-null   int64         #  9   销售成本    4248 non-null   int64         #  10  存货      4248 non-null   int64         #  11  毛利      4248 non-null   int64         #  12  利润额     4248 non-null   int64         #  13  销售额     4248 non-null   int64         # dtypes: datetime64[ns](1), int64(9), object(4)# memory usage: 464.8+ KB# =============================================================================df.head()# =============================================================================# Out[40]: #         订单日期          市场类别       区域      产品类别  ...   存货   毛利  利润额  销售额# 0 2010-01-01  Major Market  Central      一般咖啡  ...  777  130   94  219# 1 2010-01-01  Major Market  Central      一般咖啡  ...  623  107   68  190# 2 2010-01-01  Major Market  Central      一般咖啡  ...  821  139  101  234# 3 2010-01-01  Major Market  Central        普茶  ...  623   56   30  100# 4 2010-01-01  Major Market  Central  Espresso  ...  456   80   54  134# # [5 rows x 14 columns]# =============================================================================

[啤酒] 求每个区域,产品类别的平均销售额

Groupby方法

# 求每个区域,产品类别的平均销售额df.groupby(['区域', '产品类别']).agg({'销售额': 'mean'})# =============================================================================# Out[41]: #                          销售额# 区域      产品类别                # Central Espresso  207.295139#         一般咖啡      179.895833#         普茶        203.500000#         清凉茶       202.047619# East    Espresso  201.654167#         一般咖啡      337.148810#         普茶        121.882576#         清凉茶       191.486111# South   Espresso  156.215278#         一般咖啡      173.223958#         清凉茶       133.734375# West    Espresso  194.188889#         一般咖啡      185.410256#         普茶        200.611111#         清凉茶       231.692308# =============================================================================

透视表方法

# 透视表方法df.pivot_table(    index='区域', columns='产品类别', aggfunc=('mean'), values=('销售额'), fill_value=0    )# pivot_table default agg function is numpy.mean# =============================================================================# Out[46]: # 产品类别       Espresso        一般咖啡          普茶         清凉茶# 区域                                                     # Central  207.295139  179.895833  203.500000  202.047619# East     201.654167  337.148810  121.882576  191.486111# South    156.215278  173.223958    0.000000  133.734375# West     194.188889  185.410256  200.611111  231.692308# =============================================================================df.pivot_table(    index='区域', columns='产品类别', aggfunc={'销售额': np.mean, '利润额': [np.sum, np.mean]}, values=['销售额','利润额'], fill_value=0    )# 结果如下:# =============================================================================# Out[56]: #                利润额                         ...         销售额                        #               mean                         ...        mean                        # 产品类别      Espresso        一般咖啡         普茶  ...        一般咖啡          普茶         清凉茶# 区域                                         ...                                    # Central  81.600694   60.583333  66.458333  ...  179.895833  203.500000  202.047619# East     26.016667  184.476190  58.931818  ...  337.148810  121.882576  191.486111# South    52.100694   60.947917   0.000000  ...  173.223958    0.000000  133.734375# West     66.305556   27.964744  41.938889  ...  185.410256  200.611111  231.692308# # [4 rows x 12 columns]# =============================================================================

​​[啤酒] 查看2010年,各区域,产品类别的月销售额总和,并且将月份横向展示

透视表方法

df[df['订单日期'].dt.year == 2010]# =============================================================================# Out[57]: #            订单日期          市场类别       区域      产品类别  ...    存货   毛利  利润额  销售额# 0    2010-01-01  Major Market  Central      一般咖啡  ...   777  130   94  219# 1    2010-01-01  Major Market  Central      一般咖啡  ...   623  107   68  190# 2    2010-01-01  Major Market  Central      一般咖啡  ...   821  139  101  234# 3    2010-01-01  Major Market  Central        普茶  ...   623   56   30  100# 4    2010-01-01  Major Market  Central  Espresso  ...   456   80   54  134#         ...           ...      ...       ...  ...   ...  ...  ...  ...# 2119 2010-12-01  Small Market     West      一般咖啡  ...   461  104   58  176# 2120 2010-12-01  Small Market     West      一般咖啡  ...   716  145   20  250# 2121 2010-12-01  Small Market     West  Espresso  ...   567   32   13   56# 2122 2010-12-01  Small Market     West  Espresso  ...   403   80   23  145# 2123 2010-12-01  Small Market     West  Espresso  ...  1079   96   51  176# # [2124 rows x 14 columns]# =============================================================================df_2010 = df[df['订单日期'].dt.year == 2010]# month_gp = pd.Grouper(key = '订单日期', freq='M')df_2010.pivot_table(    index=['区域', '产品类别'],     columns='订单日期',     aggfunc={'销售额': np.sum},     values='销售额',     fill_value=0    )# =============================================================================# 订单日期              2010-01-01  2010-02-01  ...  2010-11-01  2010-12-01# 区域      产品类别                              ...                        # Central Espresso        2370        2432  ...        2282        2320#         一般咖啡            2663        2708  ...        2632        2813#         普茶              2649        2659  ...        2670        2860#         清凉茶             2664        2704  ...        2631        2669# East    Espresso        1853        1966  ...        2076        1981#         一般咖啡            2105        2061  ...        2066        2288#         普茶              1213        1272  ...        1231        1249#         清凉茶             1609        1621  ...        1605        1755# South   Espresso        1770        1803  ...        1796        1813#         一般咖啡            1207        1260  ...        1294        1378#         清凉茶              999        1019  ...        1115        1100# West    Espresso        2723        2759  ...        2788        2868#         一般咖啡            2339        2298  ...        2228        2293#         普茶              2789        2828  ...        2783        2921#         清凉茶             2602        2702  ...        2806        3065# # [15 rows x 12 columns]# =============================================================================

Groupby方法

keys = ['区域', '产品类别', '订单日期']df_2010.groupby(keys)['销售额'].agg('sum')# =============================================================================# Out[61]: # 区域       产品类别      订单日期      # Central  Espresso  2010-01-01    2370#                    2010-02-01    2432#                    2010-03-01    2467#                    2010-04-01    2446#                    2010-05-01    2497# # West     清凉茶       2010-08-01    3386#                    2010-09-01    2850#                    2010-10-01    2879#                    2010-11-01    2806#                    2010-12-01    3065# Name: 销售额, Length: 180, dtype: int64# =============================================================================df_2010.groupby(keys)['销售额'].agg('sum').unstack()# =============================================================================# Out[62]: # 订单日期              2010-01-01  2010-02-01  ...  2010-11-01  2010-12-01# 区域      产品类别                              ...                        # Central Espresso        2370        2432  ...        2282        2320#         一般咖啡            2663        2708  ...        2632        2813#         普茶              2649        2659  ...        2670        2860#         清凉茶             2664        2704  ...        2631        2669# East    Espresso        1853        1966  ...        2076        1981#         一般咖啡            2105        2061  ...        2066        2288#         普茶              1213        1272  ...        1231        1249#         清凉茶             1609        1621  ...        1605        1755# South   Espresso        1770        1803  ...        1796        1813#         一般咖啡            1207        1260  ...        1294        1378#         清凉茶              999        1019  ...        1115        1100# West    Espresso        2723        2759  ...        2788        2868#         一般咖啡            2339        2298  ...        2228        2293#         普茶              2789        2828  ...        2783        2921#         清凉茶             2602        2702  ...        2806        3065# # [15 rows x 12 columns]# =============================================================================

SQL Server的Pivot方法

其实,在数据库处理方法中,如SQL Server也有Pivot的方法,能够实现将数据进行行转列展示,如下图所示,将学生的成绩,在列方向按科目展示。

SQL Server Pivot方法

这里我们简单演示一下

数据准备

CREATE TABLE Grades(  [Student] VARCHAR(50),  [Subject] VARCHAR(50),  [Marks]   INT)GO INSERT INTO Grades VALUES ('Jacob','Mathematics',100),('Jacob','Science',95),('Jacob','Geography',90),('Amilee','Mathematics',90),('Amilee','Science',90),('Amilee','Geography',100)GOSELECT * FROM [dbo].[Grades];

得到了数据表集合如下:

学生成绩表

Pivot操作

;with StudentResults as (SELECT    [Student],    [Subject],    [Marks]  FROM Grades)SELECT * FROM StudentResultsPIVOT (  AVG([Marks])  FOR [Subject]  IN (    [Mathematics],    [Science],    [Geography]  )) AS PivotTable

行转列结果如下:

SQL的Pivot方法

总结

Pivot_table方法在数据展现上更加符合业务用户的习惯。

对比SQL的Pivot方法更加灵活,能够在列方向上展现多种指标,并同时实现多种聚合方法。

Mindmap after Day 8

后面我们将通过更多的例子对前期的Pandas数据分析思路进行梳理和实践。

谢谢您的时间~

参考资料

标签: #datatablecss