一、groupby分組統計
類似SQL:
select city,max(temperature) from city_weather group by city;
groupby:先對數據分組,然后在每個分組上應用聚合函數、轉換函數,官網如下:
1 分組使用聚合函數做數據統計
1)單個列groupby,查詢所有數據列的統計
我們看到:
- groupby中的'A'變成了數據的索引列
- 因為要統計sum,但B列不是數字,所以被自動忽略掉
2)多個列groupby,查詢所有數據列的統計
3)同時查看多種數據統計
我們看到:列變成了多級索引
4)查看單列的結果數據統計
5)不同列使用不同的聚合函數
2 遍歷groupby的結果理解執行流程
for循環可以直接遍歷每個group
1)遍歷單個列聚合的分組
可以獲取單個分組的數據
2)遍歷多個列聚合的分組
可以直接查詢group后的某幾列,生成Series或者子DataFrame
3 實例分組探索天氣數據
實驗數據
1)查看每個月的最高溫度
2)查看每個月的最高溫度、最低溫度、平均空氣質量指數
二、groupby聚合后不同列數據統計和合並
電影評分數據集(UserID,MovieID,Rating,Timestamp)
聚合后單列-單指標統計:每個MovieID的平均評分
- df.groupby("MovieID")["Rating"].mean()
聚合后單列-多指標統計:每個MoiveID的最高評分、最低評分、平均評分
- df.groupby("MovieID")["Rating"].agg(mean="mean", max="max", min=np.min)
- df.groupby("MovieID").agg({"Rating":['mean', 'max', np.min]})
聚合后多列-多指標統計:每個MoiveID的評分人數,最高評分、最低評分、平均評分
- df.groupby("MovieID").agg( rating_mean=("Rating", "mean"), user_count=("UserID", lambda x : x.nunique())
- df.groupby("MovieID").agg( {"Rating": ['mean', 'min', 'max'], "UserID": lambda x :x.nunique()})
- df.groupby("MovieID").apply( lambda x: pd.Series( {"min": x["Rating"].min(), "mean": x["Rating"].mean()}))
記憶:agg(新列名=函數)、agg(新列名=(原列名,函數))、agg({"原列名":函數/列表})
agg函數的兩種形式,等號代表"把結果賦值給新列",字典/元組代表"對這個列運用這些函數"
官網文檔:https://pandas.pydata.org/pandas-docs/version/0.23.4/generated/pandas.core.groupby.DataFrameGroupBy.agg.html
注意:
- 如果按一列聚合,只傳列名字符串,如果多個就要傳由列名組成的列表
- 聚合方法可以使用 Pandas 的數學統計函數 或者 Numpy 的統計函數,如果是 python 的內置統計函數,直接使用變量,不需要加引號
1 聚合后單列-單指標統計
2 聚合后單列-多指標統計
每個MoiveID的最高評分、最低評分、平均評分
方法1:agg函數傳入多個結果列名=函數名形式
方法2:agg函數傳入字典,key是column名,value是函數列表
3 聚合后多列-多指標統計
每個MoiveID的評分人數,最高評分、最低評分、平均評分
方法1:agg函數傳入字典,key是原列名,value是原列名和函數元組
方法2:agg函數傳入字典,key是原列名,value是函數列表
統計后是二級索引,需要做索引處理
方法3:使用groupby之后apply對每個子df單獨統計
4 聚合后字符串列的合並
數據
方法一
方法二
5 agg函數
agg函數一般與groupby配合使用,agg是基於列的聚合操作,而groupby是基於行的
DataFrame.agg(func,axis = 0,* args,** kwargs )
func : 函數,函數名稱,函數列表,字典{'行名/列名','函數名'}
使用指定軸上的一個或多個操作進行聚合。
6 使用字典和Series分組
import pandas as pd
路徑 = 'c:/pandas/分組聚合2.xlsx'
數據 = pd.read_excel(路徑,index_col='店號')
對應關系 = {'1月':'一季度','2月':'一季度','3月':'一季度','4月':'二季度'}
數據2 = 數據.groupby(對應關系,axis=1)
print(數據2.sum())
三、分層索引MultiIndex
為什么要學習分層索引MultiIndex?
- 分層索引:在一個軸向上擁有多個索引層級,可以表達更高維度數據的形式;
- 可以更方便的進行數據篩選,如果有序則性能更好;
- groupby等操作的結果,如果是多KEY,結果是分層索引,需要會使用
- 一般不需要自己創建分層索引(MultiIndex有構造函數但一般不用)
演示數據:百度、阿里巴巴、愛奇藝、京東四家公司的10天股票數據
數據來自:英為財經 https://cn.investing.com/
1 Series的分層索引MultiIndex
2 Series有多層索引怎樣篩選數據?
3 DataFrame的多層索引MultiIndex
4 DataFrame有多層索引怎樣篩選數據?
【重要知識】在選擇數據時:
- 元組(key1,key2)代表篩選多層索引,其中key1是索引第一級,key2是第二級,比如key1=JD, key2=2019-10-02
- 列表[key1,key2]代表同一層的多個KEY,其中key1和key2是並列的同級索引,比如key1=JD, key2=BIDU
5 多層索引的創建的方式【行】
from_arrays |
接收一個多維數組參數,高維指定高層索引,低維指定底層索引 |
from_tuples |
接收一個元組的列表,每個元組指定每個索引(高維索引,低維索引) |
from_product |
接收一個可迭代對象的列表,根據多個可迭代對象元素的笛卡爾積進行創建索引 |
注:from_product相對於前兩個方法而言,實現相對簡單,但是,也存在局限。
1)from_arrays方法
from_arrays 參數為一個二維數組,每個元素(一維數組)來分別制定每層索引的內容
import pandas as pd
多層索引 = pd.MultiIndex.from_arrays([['a', 'a', 'b', 'b'], [1, 2, 1, 2]],names=['x','y'])
2)from_tuples方法
from_tuples 參數為一個(嵌套的)可迭代對象,元素為元祖類型。元祖的格式為:(高層索引內容,低層索引內容)
import pandas as pd
多層索引 = pd.MultiIndex.from_tuples([('a',1),('a',2),('b',1),('b',2)],names=['x','y'])
3)from_product方法
使用笛卡爾積的方式來創建多層索引。參數為嵌套的可迭代對象。結果為使用每個一維數組中的元素與其他一維數組中的元素來生成 索引內容。
import pandas as pd
多層索引 = pd.MultiIndex.from_product([['a', 'b'], [1, 2]],names=['x','y'])
注:如果不在MultiIndex中設置索引名,也可以事后設置
數據.index.names = ['x', 'y']
6 多層索引的創建的方式【列】
在DataFrame中,行和列是完全對稱的,就像行可以有多個索引層次一樣,列也可以有多個層次。
index = pd.MultiIndex.from_product([[2019, 2020], [5, 6]],names=['年', '月'])
columns = pd.MultiIndex.from_product([['香蕉', '蘋果'], ['土豆', '茄子']],names=['水果', '蔬菜'])
數據 = pd.DataFrame(np.random.random(size=(4, 4)), index=index, columns=columns)
7 分層索引計算
四、stack和pivot實現數據透視
1 經過統計得到多維度指標數據
對這樣格式的數據,我想查看按月份,不同評分的次數趨勢,是沒法實現的
需要將數據變換成每個評分是一列才可以實現
2 使用unstack實現數據二維透視
目的:想要畫圖對比按照月份的不同評分的數量趨勢
3 使用pivot簡化透視
數據
pivot方法相當於對df使用set_index創建分層索引,然后調用unstack
4 stack、unstack、pivot的語法
stack:DataFrame.stack(level=-1, dropna=True),將column變成index,類似把橫放的書籍變成豎放
level=-1代表多層索引的最內層,可以通過==0、1、2指定多層索引的對應層
unstack:DataFrame.unstack(level=-1, fill_value=None),將index變成column,類似把豎放的書籍變成橫放
pivot:DataFrame.pivot(index=None, columns=None, values=None),指定index、columns、values實現二維透視