首页 > 其他分享 >数据分析第九讲:pandas 应用入门(四)

数据分析第九讲:pandas 应用入门(四)

时间:2024-06-21 23:33:12浏览次数:14  
标签:数据分析 01 入门 df sum 销售 区域 销售额 pandas

pandas 应用入门(四)

数据透视

经过前面的学习,我们已经将数据准备就绪而且变成了我们想要的样子,接下来就是最为重要的数据透视阶段了。当我们拿到一大堆数据的时候,如何从数据中迅速的解读出有价值的信息,把繁杂的数据变成容易解读的统计图表并再此基础上产生业务洞察,这就是数据分析要解决的核心问题。

获取描述性统计信息

首先,我们可以获取数据的描述性统计信息,通过描述性统计信息,我们可以了解数据的集中趋势和离散趋势。

例如,我们有如下所示的学生成绩表。

scores = np.random.randint(50, 101, (5, 3))
names = ('关羽', '张飞', '赵云', '马超', '黄忠')
courses = ('语文', '数学', '英语')
df = pd.DataFrame(data=scores, columns=courses, index=names)
df

输出:

     语文   数学   英语
关羽  96    72    73
张飞  72    70	97
赵云  74    51	79
马超  100   54	54
黄忠  89    100	88

我们可以通过DataFrame对象的方法meanmaxminstdvar等方法分别获取每个学生或每门课程的平均分、最高分、最低分、标准差、方差等信息,也可以直接通过describe方法直接获取描述性统计信息,代码如下所示。

计算每门课程成绩的平均分。

df.mean()

输出:

语文    86.2
数学    69.4
英语    78.2
dtype: float64

计算每个学生成绩的平均分。

df.mean(axis=1)

输出:

关羽    80.333333
张飞    79.666667
赵云    68.000000
马超    69.333333
黄忠    92.333333
dtype: float64

计算每门课程成绩的方差。

df.var()

输出:

语文    161.2
数学    379.8
英语    265.7
dtype: float64

说明:通过方差可以看出,数学成绩波动最大,两极分化可能更严重。

获取每门课程的描述性统计信息。

df.describe()

输出:

        语文        数学         英语
count   5.000000	5.000000	5.000000
mean    86.200000	69.400000	78.200000
std     12.696456	19.488458	16.300307
min     72.000000	51.000000	54.000000
25%     74.000000	54.000000	73.000000
50%     89.000000	70.000000	79.000000
75%     96.000000	72.000000	88.000000
max     100.000000	100.000000	97.000000
排序和取头部值

如果需要对数据进行排序,可以使用DataFrame对象的sort_values方法,该方法的by参数可以指定根据哪个列或哪些列进行排序,而ascending参数可以指定升序或是降序。例如,下面的代码展示了如何将学生表按语文成绩排降序。

df.sort_values(by='语文', ascending=False)

输出:

      语文   数学   英语
马超	100    54	  54
关羽	96     72     73
黄忠	89     100    88
赵云	74     51     79
张飞	72     70     97

如果DataFrame数据量很大,排序将是一个非常耗费时间的操作。有的时候我们只需要获得排前N名或后N名的数据,这个时候其实没有必要对整个数据进行排序,而是直接利用堆结构找出Top-N的数据。DataFramenlargestnsmallest方法就提供对Top-N操作的支持,代码如下所示。

找出语文成绩前3名的学生信息。

df.nlargest(3, '语文')

输出:

      语文   数学   英语
马超	100    54	  54
关羽	96     72     73
黄忠	89     100    88

找出数学成绩最低的3名学生的信息。

df.nsmallest(3, '数学')

输出:

      语文  数学  英语
赵云  74    51	79
马超  100   54	54
张飞  72    70	97
分组聚合

我们先从之前使用过的 Excel 文件中读取2020年销售数据,然后再为大家演示如何进行分组聚合操作。

df = pd.read_excel('data/2020年销售数据.xlsx')
df.head()

输出:

    销售日期	 销售区域   销售渠道  销售订单     品牌    售价  销售数量
0   2020-01-01  上海       拼多多    182894-455  八匹马  99    83
1   2020-01-01  上海       抖音      205635-402  八匹马  219   29
2   2020-01-01  上海       天猫      205654-021  八匹马  169   85
3   2020-01-01  上海       天猫      205654-519  八匹马  169   14
4   2020-01-01  上海       天猫      377781-010  皮皮虾  249   61

如果我们要统计每个销售区域的销售总额,可以先通过“售价”和“销售数量”计算出销售额,为DataFrame添加一个列,代码如下所示。

df['销售额'] = df['售价'] * df['销售数量']
df.head()

输出:

    销售日期	 销售区域   销售渠道  销售订单     品牌    售价  销售数量  销售额
0   2020-01-01  上海       拼多多    182894-455  八匹马  99    83        8217
1   2020-01-01  上海       抖音      205635-402  八匹马  219   29        6351
2   2020-01-01  上海       天猫      205654-021  八匹马  169   85        14365
3   2020-01-01  上海       天猫      205654-519  八匹马  169   14        2366
4   2020-01-01  上海       天猫      377781-010  皮皮虾  249   61        15189

然后再根据“销售区域”列对数据进行分组,这里我们使用的是DataFrame对象的groupby方法。分组之后,我们取“销售额”这个列在分组内进行求和处理,代码和结果如下所示。

df.groupby('销售区域').销售额.sum()

输出:

销售区域
上海    11610489
北京    12477717
安徽      895463
广东     1617949
江苏     2304380
浙江      687862
福建    10178227
Name: 销售额, dtype: int64

如果我们要统计每个月的销售总额,我们可以将“销售日期”作为groupby`方法的参数,当然这里需要先将“销售日期”处理成月,代码和结果如下所示。

df.groupby(df['销售日期'].dt.month).销售额.sum()

输出:

销售日期
1     5409855
2     4608455
3     4164972
4     3996770
5     3239005
6     2817936
7     3501304
8     2948189
9     2632960
10    2375385
11    2385283
12    1691973
Name: 销售额, dtype: int64

接下来我们将难度升级,统计每个销售区域每个月的销售总额,这又该如何处理呢?事实上,groupby方法的第一个参数可以是一个列表,列表中可以指定多个分组的依据,大家看看下面的代码和输出结果就明白了。

df.groupby(['销售区域', df['销售日期'].dt.month]).销售额.sum()

输出:

销售区域  销售日期
上海    1       1679125
        2       1689527
        3       1061193
        4       1082187
        5        841199
        6        785404
        7        863906
        8        734937
        9       1107693
        10       412108
       11       825169
       12       528041
北京    1       1878234
        2       1807787
        3       1360666
        4       1205989
        5        807300
        6       1216432
        7       1219083
        8        645727
        9        390077
        10       671608
        11       678668
        12       596146
安徽    4        341308
        5        554155
广东    3        388180
        8        469390
        9        365191
        11       395188
江苏    4        537079
        7        841032
        10       710962
        12       215307
浙江    3        248354
        8        439508
福建    1       1852496
        2       1111141
        3       1106579
        4        830207
        5       1036351
        6        816100
        7        577283
        8        658627
        9        769999
        10       580707
        11       486258
        12       352479
Name: 销售额, dtype: int64

如果希望统计出每个区域的销售总额以及每个区域单笔金额的最高和最低,我们可以在DataFrameSeries对象上使用agg方法并指定多个聚合函数,代码和结果如下所示。

df.groupby('销售区域').销售额.agg(['sum', 'max', 'min'])

输出:

           sum     max   min
销售区域                        
上海    11610489  116303   948
北京    12477717  133411   690
安徽      895463   68502  1683
广东     1617949  120807   990
江苏     2304380  114312  1089
浙江      687862   90909  3927
福建    10178227   87527   897

如果希望自定义聚合后的列的名字,可以使用如下所示的方法。

df.groupby('销售区域').销售额.agg(销售总额='sum', 单笔最高='max', 单笔最低='min')

输出:

          销售总额    单笔最高  单笔最低
销售区域                        
上海      11610489     116303     948
北京      12477717     133411     690
安徽        895463      68502    1683
广东       1617949     120807     990
江苏       2304380     114312    1089
浙江        687862      90909    3927
福建      10178227      87527     897

如果需要对多个列使用不同的聚合函数,例如“统计每个销售区域销售额的总和以及销售数量的最低值和最高值”,我们可以按照下面的方式来操作。

df.groupby('销售区域')[['销售额', '销售数量']].agg({
    '销售额': 'sum', '销售数量': ['max', 'min']
})

输出:

           销售额  销售数量    
           sum    max min
销售区域                   
上海    11610489  100  10
北京    12477717  100  10
安徽      895463   98  16
广东     1617949   98  10
江苏     2304380  100  11
浙江      687862   95  20
福建    10178227  100  10
透视表和交叉表

上面的例子中,“统计每个销售区域每个月的销售总额”会产生一个看起来很长的结果,在实际工作中我们通常把那些行很多列很少的表成为“窄表”,如果我们不想得到这样的一个“窄表”,可以使用DataFramepivot_table方法或者是pivot_table函数来生成透视表。透视表的本质就是对数据进行分组聚合操作,根据 A 列对 B 列进行统计,如果大家有使用 Excel 的经验,相信对透视表这个概念一定不会陌生。例如,我们要“统计每个销售区域的销售总额”,那么“销售区域”就是我们的 A 列,而“销售额”就是我们的 B 列,在pivot_table函数中分别对应indexvalues参数,这两个参数都可以是单个列或者多个列。

pd.pivot_table(df, index='销售区域', values='销售额', aggfunc='sum')

输出:

           销售额
销售区域          
上海    11610489
北京    12477717
安徽      895463
广东     1617949
江苏     2304380
浙江      687862
福建    10178227

注意:上面的结果操作跟之前用groupby的方式得到的结果有一些区别,groupby操作后,如果对单个列进行聚合,得到的结果是一个Series对象,而上面的结果是一个DataFrame 对象。

如果要统计每个销售区域每个月的销售总额,也可以使用pivot_table函数,代码如下所示。

df['月份'] = df['销售日期'].dt.month
pd.pivot_table(df, index=['销售区域', '月份'], values='销售额', aggfunc='sum')

上面的操作结果是一个DataFrame,但也是一个长长的“窄表”,如果希望做成一个行比较少列比较多的“宽表”,可以将index参数中的列放到columns参数中,代码如下所示。

pd.pivot_table(df, index='销售区域', columns='月份', values='销售额', aggfunc='sum', fill_value=0)

说明pivot_table函数的fill_value=0会将空值处理为0

输出:

使用pivot_table函数时,还可以通过添加marginsmargins_name参数对分组聚合的结果做一个汇总,具体的操作和效果如下所示。

pd.pivot_table(df, index='销售区域', columns='月份', values='销售额', aggfunc='sum', fill_value=0, margins=True, margins_name='总计')

输出:

交叉表就是一种特殊的透视表,它不需要先构造一个DataFrame对象,而是直接通过数组或Series对象指定两个或多个因素进行运算得到统计结果。例如,我们要统计每个销售区域的销售总额,也可以按照如下所示的方式来完成,我们先准备三组数据。

sales_area, sales_month, sales_amount = df['销售区域'], df['月份'], df['销售额']

使用crosstab函数生成交叉表。

pd.crosstab(index=sales_area, columns=sales_month, values=sales_amount, aggfunc='sum').fillna(0).astype('i8')

说明:上面的代码使用了DataFrame对象的fillna方法将空值处理为0,再使用astype方法将数据类型处理成整数。

数据呈现

一图胜千言,我们对数据进行透视的结果,最终要通过图表的方式呈现出来,因为图表具有极强的表现力,能够让我们迅速的解读数据中隐藏的价值。和Series一样,DataFrame对象提供了plot方法来支持绘图,底层仍然是通过matplotlib库实现图表的渲染。关于matplotlib的内容,我们在下一个章节进行详细的探讨,这里我们只简单的讲解plot方法的用法。

例如,我们想通过一张柱状图来比较“每个销售区域的销售总额”,可以直接在透视表上使用plot方法生成柱状图。我们先导入matplotlib.pyplot模块,通过修改绘图的参数使其支持中文显示。

import matplotlib.pyplot as plt

plt.rcParams['font.sans-serif'] = 'FZJKai-Z03S'

说明:上面的FZJKai-Z03S是我电脑上已经安装的一种支持中文的字体的名称,字体的名称可以通过查看用户主目录下.matplotlib文件夹下名为fontlist-v330.json的文件来获得,而这个文件在执行上面的命令后就会生成。

使用魔法指令配置生成矢量图。

%config InlineBackend.figure_format = 'svg'

绘制“每个销售区域销售总额”的柱状图。

temp = pd.pivot_table(df, index='销售区域', values='销售额', aggfunc='sum')
temp.plot(figsize=(8, 4), kind='bar')
plt.xticks(rotation=0)
plt.show()

说明:上面的第3行代码会将横轴刻度上的文字旋转到0度,第4行代码会显示图像。

输出:

如果要绘制饼图,可以修改plot方法的kind参数为pie,然后使用定制饼图的参数对图表加以定制,代码如下所示。

temp.sort_values(by='销售额', ascending=False).plot(
    figsize=(6, 6),
    kind='pie',
    y='销售额',
    ylabel='',
    autopct='%.2f%%',
    pctdistance=0.8,
    wedgeprops=dict(linewidth=1, width=0.35),
    legend=False
)
plt.show()

输出:

标签:数据分析,01,入门,df,sum,销售,区域,销售额,pandas
From: https://blog.csdn.net/weixin_46863529/article/details/139741002

相关文章

  • 【面向就业的Linux基础】从入门到熟练,探索Linux的秘密(三)-shell语法
    主要通过讲解shell中的一些基本语法,可以当作日常的笔记来进行查询和记忆。文章目录前言一、shell二、shell语法1.运行方式2.注释3.变量4.默认变量 5.数组 总结前言主要通过讲解shell中的一些基本语法,可以当作日常的笔记来进行查询和记忆。提示:以下是本篇......
  • SQL学习记录 #1、入门:增删改查
    1. 通识SQL语句可以单行或多行书写,以分号结尾。SQL语句可以单独使用空格/缩进来增强语句的可读性。Mysql数据库的SQL语句不区分大小写,关键字建议使用大写。注释:单行注释:-- 注释内容或# 注释内容多行注释:/*注释内容*/2.分类分类概述说明DDL(DataDefinitionLangua......
  • opencv入门-小白的学习笔记c++(1)
    注:以下是根据链接https://blog.csdn.net/Cream_Cicilian/article/details/105427752的小白学习过程。1加载、修改、保存图像1.1加载图像1.1.1加载图像cv::imread用于从文件中读取图像数据并将其存储到一个cv::Mat对象中,其中第一个参数表示图像文件名称第二个参数,表......
  • 【每日一练】python入门级小案例
    题目数字从小到大排序 用户随意分别输入三个数,利用列表的排序方法sort()从小到大排序。代码: 输出结果: 代码分析:先创建三个变量x,y,z,用input()输入获取值;再创建一个列表,元素分别是x,y,z三个变量;利用列表的排序方法sort(),对列表从小到大排序;用for循环遍......
  • docker入门
    前言Docker诞生于2013年,由SolomonHykes在DotCloud公司(后更名为Docker,Inc.)创立。Docker的核心理念是**“Build,Ship,andRunAnywhere”**,即构建、发布、运行应用程序不受环境限制。Docker通过容器化技术,将应用及其所有依赖打包到一个独立的、可移植的单元中,从而实现了......
  • Flask新手入门(一)
    前言Flask是一个用Python编写的轻量级Web应用框架。它最初由ArminRonacher作为Werkzeug的一个子项目在2010年开发出来。Werkzeug是一个综合工具包,提供了各种用于Web应用开发的工具和函数。自发布以来,Flask因其简洁和灵活性而迅速受到开发者的欢迎。随着Python社区的增长,Fl......
  • Windows C++ 应用软件开发从入门到精通详解
    目录1、引言2、IDE开发环境介绍2.1、VisualStudio 2.2、QTCreator3、Windows平台实用小工具介绍3.1、代码编辑器VSCode3.2、代码查看编辑器SourceInsight3.3、文本编辑器Notepad++3.4、文件搜索工具Everything4、C++语言特性4.1、熟悉泛型编程4.2、了解......
  • Java入门指南:大一新生的编程初体验
    引言作为一名大一新生,踏入编程世界可能会让人感到既兴奋又有些忐忑。Java作为一种广泛使用的编程语言,以其强大的功能和跨平台的特性,成为了许多计算机科学课程的首选。本文将带你一起走进Java的世界,分享一些入门的知识和学习经验,希望对刚开始学习Java的你有所帮助。1.为什么......
  • 数据分析---matplotlib模块的使用
    1.摘要在数据可视化、统计绘图和图表生成领域,Python被广泛使用,其中Matplotlib是一个极其重要的基础三方库。本博客旨在介绍Python及其三方库Matplotlib的详细信息,包括Matplotlib的安装步骤、示例代码及使用注意事项。2.引言2.1什么是Matplotlib?Matplotlib是一......
  • vscode python编程入门与插件推荐
    使用背景作者是一名ai测开工程师,工作环境中通常会使用到pythonshellpostgresql数据库jupyter,shh工具git版本控制等,因此向选用一个适合自己的文本编辑软件,经过长时间磨合,最终选择VScode作为我的工作软件优点内存占用率低,集成度高,开源免费插件推荐AI助手:codegeex此插件......