zoukankan      html  css  js  c++  java
  • 小白学 Python 数据分析(11):Pandas (十)数据分组

    人生苦短,我用 Python

    前文传送门:

    小白学 Python 数据分析(1):数据分析基础

    小白学 Python 数据分析(2):Pandas (一)概述

    小白学 Python 数据分析(3):Pandas (二)数据结构 Series

    小白学 Python 数据分析(4):Pandas (三)数据结构 DataFrame

    小白学 Python 数据分析(5):Pandas (四)基础操作(1)查看数据

    小白学 Python 数据分析(6):Pandas (五)基础操作(2)数据选择

    小白学 Python 数据分析(7):Pandas (六)数据导入

    小白学 Python 数据分析(8):Pandas (七)数据预处理

    小白学 Python 数据分析(9):Pandas (八)数据预处理(2)

    小白学 Python 数据分析(10):Pandas (九)数据运算

    引言

    各位同学好呀,我又出来了,本篇文章我们介绍下 Pandas 的数据分组。

    本文用的数据集再次做更换,有同学在后台问小编为什么最近每篇文章都在换数据集。

    emmmmmmmm,在小白刚入门的时候,很多同学找不到数据集练手,小编尽量多使用一些数据集,传到代码仓库后,大家 Down 下来直接就能使用,给大家多提供几个案例做选择。

    AkShare

    本次的数据集选择由 AkShare 提供的本次疫情的历史数据。

    摘取一段 AkShare 官网的介绍,各位同学大致了解下 AkShare :

    AkShare 的简介:

    AkShare 是基于 Python 的开源金融数据接口库, 目的是实现对股票, 期货, 期权, 基金, 外汇, 债券, 指数, 数字货币等金融产品的基本面数据、实时和历史行情数据、衍生数据从数据采集, 数据清洗, 到数据落地的一套开源工具, 满足金融数据科学家, 数据科学爱好者在金融数据获取方面的需求.

    AkShare 的特点是获取的是相对权威的金融数据网站公布的原始数据, 广大数据科学家可以利用原始数据进行各数据源之间的交叉验证, 进而再加工, 从而得出科学的结论.

    好像和疫情没什么关系么,其实 AkShare 也是在最近的更新中添加了有关本次疫情的数据集。

    首先第一件事儿就是先把我们今天要使用到的数据集搞下来,首先是 AkShare 的安装,参考文档示例进行安装( https://akshare.readthedocs.io/zh_CN/latest/akshare/ak-installation.html ):

    通用安装:

    pip install akshare  --upgrade
    

    国内安装-Python:

    pip install akshare -i http://mirrors.aliyun.com/pypi/simple/ --trusted-host=mirrors.aliyun.com  --upgrade
    

    国内安装-Anaconda:

    pip install akshare -i http://mirrors.aliyun.com/pypi/simple/ --trusted-host=mirrors.aliyun.com  --user  --upgrade
    

    除了一些 Python 的库需要进行安装,还有一些其他环境需要安装,小编这里就不一一列出了,请各位同学参考文档进行安装。

    安装好以后,将本次疫情的历史数据进行导出成 Excel ,然后开始我们今天的正题,这段导出代码其实非常简单,加上导包总共三行,如下:

    import akshare as ak
    
    epidemic_dxy_df = ak.epidemic_dxy(indicator="global")
    epidemic_dxy_df.to_excel('epidemic_dxy.xlsx')
    

    这里获取的其实是本次疫情截止小编写这篇文章时的一个最新数据。

    说明: epidemic_dxy_df 是一个 DataFrame ,这里直接通过 DataFrame 的 to_excel 进行 Excel 导出。

    如果不想使用 Excel 的同学,也可以直接操作 epidemic_dxy_df 这个 DataFrame ,只是每次运行的时候它都要从远端拉取数据,速度上挺慢的,从本地的 Excel 中读取数据还是会快很多。

    导出的 Excel 小编就简单截个图,如图:

    可以看到,总共有 66 行的数据,数据量不大,我们进行操作后,可以人工核实操作数据是否正确。

    数据分组

    如果有对 SQL 使用经验的同学来讲,分组这个词并不陌生,在 SQL 中的关键字是 group by ,而在 Pandas 中的方法名也十分相似,是 groupby()

    当然,如果对 SQL 不熟悉的同学也可以参考下 Excel 的分组,都是一样的。

    我们先按照七大洲对这个数据做一次分组,看下是什么结果:

    import pandas as pd
    
    # 数据导入
    epidemic_dxy = pd.read_excel("epidemic_dxy.xlsx")
    
    print(epidemic_dxy.groupby(['continents']))
    
    # 输出内容
    <pandas.core.groupby.generic.DataFrameGroupBy object at 0x0000019AB24BAB48>
    

    可以看到,这里输出的了一个 DataFrameGroupBy 的内存对象,实际上这个对象中包含了分组后的一些相关信息,并没有直接显示出来,我们直接调用一个汇总的方法看一下:

    print(epidemic_dxy.groupby(['continents']).count())
    
    # 输出内容
                id  createTime  modifyTime  ...  operator  locationId  countryShortCode
    continents                              ...                                        
    亚洲          26          26          26  ...        26          26                26
    其他           1           1           1  ...         1           1                 1
    北美洲          4           4           4  ...         4           4                 4
    南美洲          2           2           2  ...         2           2                 2
    大洋洲          2           2           2  ...         2           2                 2
    欧洲          27          27          27  ...        27          27                27
    非洲           3           3           3  ...         3           3                 3
    

    count() 的含义是取计数,就是当前的数据有多少条,可以看到,亚洲有 26 条数据。

    如果我想知道当前七大洲的汇总数据呢?可以用到 sum() 这个方法:

    import pandas as pd
    
    # 数据导入
    epidemic_dxy = pd.read_excel("epidemic_dxy.xlsx")
    
    pd.set_option('display.max_columns', None)
    print(epidemic_dxy.groupby(['continents']).sum())
    
    # 输出内容
                      id      createTime      modifyTime  tags  countryType  
    continents                                                                
    亚洲          18446021  41161613744000  41161613744000   0.0           52   
    其他            709404   1583138990000   1583138990000   0.0            2   
    北美洲          2838116   6332555961000   6332555961000   0.0            8   
    南美洲          1419041   3166277981000   3166277981000   0.0            4   
    大洋洲          1418867   3166277980000   3166277980000   0.0            4   
    欧洲          19156076  42744752735000  42744752735000   0.0           54   
    非洲           2128329   4749416970000   4749416970000   0.0            6   
    
                provinceId  provinceShortName  cityName  currentConfirmedCount  
    continents                                                                   
    亚洲                 231                0.0       0.0                   5458   
    其他                  10                0.0       0.0                    699   
    北美洲                 38                0.0       0.0                     99   
    南美洲                 20                0.0       0.0                      8   
    大洋洲                 20                0.0       0.0                     14   
    欧洲                 265                0.0       0.0                   2040   
    非洲                  30                0.0       0.0                      3   
    
                confirmedCount  suspectedCount  curedCount  deadCount  comment  
    continents                                                                   
    亚洲                    5940               0         399         83      0.0   
    其他                     705               0           0          6      0.0   
    北美洲                    107               0           7          1      0.0   
    南美洲                      8               0           0          0      0.0   
    大洋洲                     30               0          15          1      0.0   
    欧洲                    2199               0         123         36      0.0   
    非洲                       4               0           1          0      0.0   
    
                sort  locationId  
    continents                    
    亚洲             0    24793190  
    其他             0           0  
    北美洲            0     3887012  
    南美洲            0     1946009  
    大洋洲            0     1980008  
    欧洲             0    25035128  
    非洲             0     2944016  
    

    因为原始数据有点多,小编这里将所有的列全展示出来,可以看到亚洲目前的确诊数量是 5940 ,当然,这里不包含中国的数据。

    这里的列太多了,很多列并不是我们关心的,如果我们只关心几个核心的数据怎么展示呢?

    我们可以先分组,分组后取出我们需要的列,然后再对列做运算,如下:

    import pandas as pd
    
    # 数据导入
    epidemic_dxy = pd.read_excel("epidemic_dxy.xlsx")
    
    print(epidemic_dxy.groupby(['continents'])['confirmedCount', 'suspectedCount', 'curedCount', 'deadCount'].sum())
    
    # 输出内容
                confirmedCount  suspectedCount  curedCount  deadCount
    continents                                                       
    亚洲                    5940               0         399         83
    其他                     705               0           0          6
    北美洲                    107               0           7          1
    南美洲                      8               0           0          0
    大洋洲                     30               0          15          1
    欧洲                    2199               0         123         36
    非洲                       4               0           1          0
    

    在进行数据分组的时候,我们除了可以使用列名进行分组,还可以使用 Series 进行分组,它与使用列名进行分组在使用上没有任何不同:

    import pandas as pd
    
    # 数据导入
    epidemic_dxy = pd.read_excel("epidemic_dxy.xlsx")
    
    print(epidemic_dxy.groupby(epidemic_dxy['continents'])['confirmedCount', 'suspectedCount', 'curedCount', 'deadCount'].sum())
    
    # 输出内容
                confirmedCount  suspectedCount  curedCount  deadCount
    continents                                                       
    亚洲                    5940               0         399         83
    其他                     705               0           0          6
    北美洲                    107               0           7          1
    南美洲                      8               0           0          0
    大洋洲                     30               0          15          1
    欧洲                    2199               0         123         36
    非洲                       4               0           1          0
    

    这里的 epidemic_dxy['continents'] 本身就是一个 Series ,可以看到和上面使用列名进行分组无任何不同。

    在分组的时候,除了可以使用一个列或者 Series ,还可以使用多个,只需要在 groupby() 的参数中进行添加即可,如下:

    import pandas as pd
    
    # 数据导入
    epidemic_dxy = pd.read_excel("epidemic_dxy.xlsx")
    
    print(epidemic_dxy.groupby([epidemic_dxy['continents'], epidemic_dxy['provinceName']])['confirmedCount', 'suspectedCount', 'curedCount', 'deadCount'].sum())
    
    # 输出内容
                             confirmedCount  suspectedCount  curedCount  deadCount
    continents provinceName                                                       
    亚洲         亚美尼亚                       1               0           0          0
               以色列                       10               0           1          0
               伊拉克                       19               0           0          0
               伊朗                       978               0         175         54
               卡塔尔                        1               0           0          0
    ...                                 ...             ...         ...        ...
    欧洲         荷兰                        10               0           0          0
               西班牙                       84               0           2          0
    非洲         埃及                         2               0           1          0
               尼日利亚                       1               0           0          0
               阿尔及利亚                      1               0           0          0
    
    [65 rows x 4 columns]
    

    我们这里使用了七大洲和国家进行分组,可以看到整个求和的数据集已经按照七大洲和国家求和列出了。

    你以为分组到这里就算完了?

    nonono,下面还有个神奇的家伙 —— aggregate()

    aggregate() 这个方法是做什么的呢?

    如果我们想在一次分组中,进行两次汇总运算,那么,就要用到这个函数了,比如,我想在刚才的数据中先计数,在求和,那么可以这么写:

    import pandas as pd
    
    # 数据导入
    epidemic_dxy = pd.read_excel("epidemic_dxy.xlsx")
    
    print(epidemic_dxy.groupby(epidemic_dxy['continents'])['confirmedCount', 'suspectedCount', 'curedCount', 'deadCount'].aggregate(['count', 'sum']))
    
    # 输出内容
                        count   sum          count  ...        sum     count sum
    continents                                      ...                         
    亚洲                     26  5940             26  ...        399        26  83
    其他                      1   705              1  ...          0         1   6
    北美洲                     4   107              4  ...          7         4   1
    南美洲                     2     8              2  ...          0         2   0
    大洋洲                     2    30              2  ...         15         2   1
    欧洲                     27  2199             27  ...        123        27  36
    非洲                      3     4              3  ...          1         3   0
    
    [7 rows x 8 columns]
    

    怎么样,是不是很神奇,左边是计数,右边是求和。

    不过有一点要注意下,在我们对数据进行分组运算完成后,有时候会需要对数据进行进一步的处理,由于分组运算后的结果并不是标准的 DataFrame 形式,需要我们对它进行进一步的转化,这里用到的方法就是重置索引 reset_index()

    import pandas as pd
    
    # 数据导入
    epidemic_dxy = pd.read_excel("epidemic_dxy.xlsx")
    
    new_dataframe = epidemic_dxy.groupby(epidemic_dxy['continents'])['confirmedCount', 'suspectedCount', 'curedCount', 'deadCount'].sum().reset_index()
    
    print(new_dataframe)
    
    # 输出内容
      continents  confirmedCount  suspectedCount  curedCount  deadCount
    0         亚洲            5940               0         399         83
    1         其他             705               0           0          6
    2        北美洲             107               0           7          1
    3        南美洲               8               0           0          0
    4        大洋洲              30               0          15          1
    5         欧洲            2199               0         123         36
    6         非洲               4               0           1          0
    

    这样,我们就得到了一个新的 DataFrame ,可以在这个新的 DataFrame 进行新的骚操作了。

    本篇的内容到这里才算结束,各位看更的同学,记得要手写代码哦~~~

    示例代码

    老规矩,所有的示例代码都会上传至代码管理仓库 Github 和 Gitee 上,方便大家取用。

    示例代码-Github

    示例代码-Gitee

  • 相关阅读:
    UVALive 3664:Guess(贪心 Grade E)
    uva 1611:Crane(构造 Grade D)
    uva 177:Paper Folding(模拟 Grade D)
    UVALive 6514:Crusher’s Code(概率dp)
    uva 11491:Erasing and Winning(贪心)
    uva 1149:Bin Packing(贪心)
    uva 1442:Cave(贪心)
    学习 linux第一天
    字符编码问题
    orm 正向查询 反向查询
  • 原文地址:https://www.cnblogs.com/babycomeon/p/12407585.html
Copyright © 2011-2022 走看看