1. 程式人生 > >小白學 Python 資料分析(11):Pandas (十)資料分組

小白學 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 :

  • Github 地址: https://github.com/jindaxiang/akshare

  • 中文文件地址: https://akshare.readthedocs.io/zh_CN/latest/

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

示例程式碼-Gi