Pandas 數(shù)據(jù)重塑
1. 前言
上一節(jié)我們學(xué)習(xí)了 Pandas 層次化索引的概念,可以用來表示更高維度的數(shù)據(jù)集。我們前面學(xué)習(xí)的數(shù)據(jù)處理大多是在數(shù)據(jù)值層面進(jìn)行操作,有時(shí)候的數(shù)據(jù)分析僅僅靠數(shù)據(jù)值的處理是完全不夠的,還要對(duì)數(shù)據(jù)的結(jié)構(gòu)做處理,使其更加適合分析的需要,那 Pandas 庫又提供了怎樣的操作來實(shí)現(xiàn)這類需要呢?
Pandas 提供了數(shù)據(jù)重塑 / 軸向旋轉(zhuǎn)的操作來對(duì)數(shù)據(jù)進(jìn)行重新排列,實(shí)現(xiàn)數(shù)據(jù)的結(jié)構(gòu)變化,本節(jié)課我們將一起學(xué)習(xí)該操作的具體實(shí)現(xiàn)方式,主要涉及到 stack () ,unstack () 和 pivot () 三個(gè)操作函數(shù)。
2. 數(shù)據(jù)重塑
Pandas 對(duì)應(yīng)數(shù)據(jù)的重塑有三種操作方式,分別為重塑操作 stack () , unstack () 和軸向旋轉(zhuǎn)操作 pivot ():
- stack ():該操作是將數(shù)據(jù)的列 “旋轉(zhuǎn)” 為行;
- unstack ():該操作是將數(shù)據(jù)的行 “旋轉(zhuǎn)” 為列。
下面我們先構(gòu)造一些模擬數(shù)據(jù),然后詳細(xì)講解這兩種數(shù)據(jù)重塑的方式:
# 導(dǎo)入 Pandas 庫
import pandas as pd
# 構(gòu)造數(shù)據(jù)集
df_data=pd.DataFrame([[96,92,83,94],[85,86,77,88],[69,90,91,82]],
index=['語文','數(shù)學(xué)','英語'],
columns=['月考1','月考2','月考3','月考4'])
print(df_data)
# --- 輸出結(jié)果 ---
月考1 月考2 月考3 月考4
語文 96 92 83 94
數(shù)學(xué) 85 86 77 88
英語 69 90 91 82
# 結(jié)果解析:這就是我們前面幾節(jié)課學(xué)習(xí)的,創(chuàng)建一個(gè) DataFrame 數(shù)據(jù)集的方式。
# 接下來我們?yōu)?df_data 數(shù)據(jù)集指定行索引和列索引的索引名,分別為 “科目”,“模考”,這里要注意索引名和索引值的區(qū)別,我們上面的 index 和 columns 參數(shù)指定的是行索引和列索引值。
df_data.index.name='科目'
df_data.columns.name='模考'
print(df_data)
# --- 輸出結(jié)果 ---
??? 月考1 月考2 月考3 月考4
科目
語文 96 92 83 94
數(shù)學(xué) 85 86 77 88
英語 69 90 91 82
# 結(jié)果解析:這里可以看到 df_data 數(shù)據(jù)集中有了行索引名“科目”和列索引名“模考”。
1. stack() 函數(shù)
通過該函數(shù),我們將 df_data 數(shù)據(jù)集的數(shù)據(jù)列轉(zhuǎn)為數(shù)據(jù)行:
# df_data 為上述構(gòu)建的數(shù)據(jù)集
print(df_data.stack())
# --- 輸出結(jié)果 ---
科目 ???
語文 月考1 96
月考2 92
月考3 83
月考4 94
數(shù)學(xué) 月考1 85
月考2 86
月考3 77
月考4 88
英語 月考1 69
月考2 90
月考3 91
月考4 82
結(jié)果解析:通過列旋轉(zhuǎn)為行的重塑方式,我們看月考列數(shù)據(jù)變?yōu)榱诵袛?shù)據(jù),得到數(shù)據(jù)集有了層次化的列索引,一維的 “科目”,二維的 “??肌?,這樣的數(shù)據(jù)結(jié)構(gòu)對(duì)于我們分析每科在各次月考中成績的變化有很好的幫助。
2. unstack() 函數(shù)
通過該函數(shù),我們將 df_data 數(shù)據(jù)集的數(shù)據(jù)行轉(zhuǎn)為數(shù)據(jù)列:
# df_data 為上述構(gòu)建的數(shù)據(jù)集
print(df_data.unstack())
# --- 輸出結(jié)果 ---
??? 科目
月考1 語文 96
數(shù)學(xué) 85
英語 69
月考2 語文 92
數(shù)學(xué) 86
英語 90
月考3 語文 83
數(shù)學(xué) 77
英語 91
月考4 語文 94
數(shù)學(xué) 88
英語 82
結(jié)果解析:這里可以看到,原數(shù)據(jù)中的科目行數(shù)據(jù),變?yōu)榱肆袛?shù)據(jù),索引也是層次化的索引,對(duì)于我們分析每次月考各科目成績的波動(dòng)有很好的幫助。
如果我們對(duì) stack () 操作后返回的數(shù)據(jù)集,再進(jìn)行 unstack () 操作,會(huì)發(fā)現(xiàn)回到了原數(shù)據(jù)結(jié)構(gòu),說明 unstack () 是 stack () 的逆操作:
print(df_data.stack().unstack())
# --- 輸出結(jié)果 ---
??? 月考1 月考2 月考3 月考4
科目
語文 96 92 83 94
數(shù)學(xué) 85 86 77 88
英語 69 90 91 82
3. pivot() 函數(shù)
該函數(shù)用于指定行索引,列索引,以及數(shù)據(jù)值,生成一個(gè) “pivot” 數(shù)據(jù)表格。該函數(shù)有三個(gè)參數(shù):
參數(shù)名 | 說明 |
---|---|
index | 新數(shù)據(jù)集的列索引 |
columns | 新數(shù)據(jù)集的行索引 |
values | 對(duì)應(yīng)行和列所要填充的數(shù)據(jù)值,如果沒有,填充 NaN |
下面我們先模擬一個(gè) DataFrame 數(shù)據(jù)集,便于該函數(shù)的操作效果展示:
# 這里模擬了3年某位學(xué)生各學(xué)期語文、數(shù)學(xué)得分的數(shù)據(jù)表。
df_data_pivot=pd.DataFrame([["2018","上學(xué)期",83,94],["2018","下學(xué)期",77,88],
["2019","上學(xué)期",83,94],["2019","下學(xué)期",83,94],
["2020","上學(xué)期",83,94],["2020","下學(xué)期",91,82]],
index=['a','b','c','d','e','f'],
columns=['年度','學(xué)期','語文','數(shù)學(xué)'])
print(df_data_pivot)
# --- 輸出結(jié)果 ---
年度 學(xué)期 語文 數(shù)學(xué)
a 2018 上學(xué)期 83 94
b 2018 下學(xué)期 77 88
c 2019 上學(xué)期 83 94
d 2019 下學(xué)期 83 94
e 2020 上學(xué)期 83 94
f 2020 下學(xué)期 91 82
接下來我們將通過函數(shù) pivot () 指定行索引、列索引以及數(shù)據(jù)值,生成新的數(shù)據(jù)集:
# pivot(index="年度", columns="學(xué)期", values="語文")
new_df=df_data_pivot.pivot(index="年度", columns="學(xué)期", values="語文")
print(new_df)
# --- 輸出結(jié)果 ---
學(xué)期 上學(xué)期 下學(xué)期
年度
2018 83 77
2019 83 83
2020 83 91
輸出解析:我們這里指定行索引為年度,列索引為學(xué)期,填充對(duì)應(yīng)行和列索引的語文數(shù)據(jù)值,通過輸出結(jié)果可以看到新的數(shù)據(jù)集,這樣處理之后的數(shù)據(jù)結(jié)構(gòu)是很利于我們分析各年度各學(xué)期語文成績的一個(gè)變化情況。
3. 小結(jié)
本節(jié)課程我們主要學(xué)習(xí)了 Pandas 庫對(duì)于數(shù)據(jù)的重塑操作,該操作能有效的滿足我們對(duì)原數(shù)據(jù)的數(shù)據(jù)結(jié)構(gòu)的變換操作,進(jìn)而滿足我們對(duì)數(shù)據(jù)不同的分析需要。本節(jié)課程的重點(diǎn)如下:
- stack () 函數(shù)和 unstack () 函數(shù)的具體操作方法,以及他們之間的區(qū)別;
- pivot () 函數(shù)的使用條件和操作方法。