在家為國家做貢獻太無聊,不如跟我一起學點 Python
人生苦短,我用 Python
前文傳送門:
小白學 Python 數據分析(2):Pandas (一)概述
小白學 Python 數據分析(3):Pandas (二)數據結構 Series
小白學 Python 數據分析(4):Pandas (三)數據結構 DataFrame
引言
最近這個系列有段時間沒更新,理由也就不找了,總結就一點,懶!懶得學習!
我就是這么一個能勇於發現並且承認錯誤的人。
不過從這篇開始,我又恢復更新了,手動滑稽一下:)
接下來小編要分享一些 Pandas 的基礎操作,可能會有些無聊,不過還是希望有興趣的同學能對照着代碼自己動手敲一下。
閑話不多聊,下面開始正題。
查看數據
前面的兩篇內容中,我們介紹了 Pandas 的兩種數據結構,本篇的內容將主要介紹一些有關於 DataFrame 的查找操作,畢竟 DataFrame 是一個二維類似於表一樣的數據結構,我們平時會更多的使用 DataFrame 。
首先第一部還是導入 Pandas 與 NumPy ,並且要生成一個 DataFrame ,這里小編就簡單的使用隨機數的形式進行生成,代碼如下:
import numpy as np
import pandas as pd
dates = pd.date_range('20200101', periods=6)
df = pd.DataFrame(np.random.randn(6, 4), index=dates, columns=list('ABCD'))
print(df)
這里最后我們打印了一下這個生成的 DataFrame ,結果如下:
A B C D
2020-01-01 0.177499 -0.025693 0.182894 -1.123577
2020-01-02 1.067580 1.592576 -0.010205 -0.349342
2020-01-03 1.141218 1.032333 1.364477 0.851630
2020-01-04 0.920260 -0.243247 0.196369 -0.835655
2020-01-05 -0.729184 -0.235706 1.144007 -1.048619
2020-01-06 -0.480888 -0.995325 -0.283726 0.428644
以上我們的准備工作就完成了,已經構建了一個隨機產生的 DataFrame ,接下來我們看一些簡單的取值操作。
首先第一個是從頭部開始取值,這里使用到的方法是 head()
,比如現在需要取出上面這個 df 中第一行的數據,那我們可以這么寫:
# 查看頭部數據
print(df.head(1))
結果如下:
A B C D
2020-01-01 0.177499 -0.025693 0.182894 -1.123577
既然有從頭部取數那么一定會有從尾部取數,這個方法是 tail()
,用法和上面的一樣,這里我們從尾部取出兩行的數據,如下:
# 查看尾部數據
print(df.tail(2))
結果如下:
A B C D
2020-01-05 -0.729184 -0.235706 1.144007 -1.048619
2020-01-06 -0.480888 -0.995325 -0.283726 0.428644
對照看之前的 df ,可以看到計算機成功完成了我們的目標。
接下來,我們獲取這個 df 的索引,這里可以用到的方法是 index
,如下:
# 獲取索引
print(df.index)
結果如下:
DatetimeIndex(['2020-01-01', '2020-01-02', '2020-01-03', '2020-01-04',
'2020-01-05', '2020-01-06'],
dtype='datetime64[ns]', freq='D')
能獲取索引那么就一定能獲取所有的列名,這個方法大家可能都猜到了,就是 columns
,沒毛病, Pandas 的命名還是很友好的,直接就是英文翻譯,多的我這里就不吐槽了,命名不規范的代碼經常性的會造成他人的誤解,所以建議各位盡量命名規范一點:
# 獲取列名
print(df.columns)
結果如下:
Index(['A', 'B', 'C', 'D'], dtype='object')
這里 Pandas 還為我們提供了一個很 NB 的方法,就是直接快速查看數據的統計摘要,這個方法是 describe()
,這個方法可以讓我們簡單的知道一個我們不清楚內容的 DataFrame 里面具體內容,如下:
# 查看數據的統計摘要
print(df.describe())
結果如下:
A B C D
count 6.000000 6.000000 6.000000 6.000000
mean 0.349414 0.187490 0.432303 -0.346153
std 0.818647 0.948383 0.663604 0.821275
min -0.729184 -0.995325 -0.283726 -1.123577
25% -0.316291 -0.241362 0.038070 -0.995378
50% 0.548879 -0.130700 0.189632 -0.592498
75% 1.030750 0.767826 0.907098 0.234148
max 1.141218 1.592576 1.364477 0.851630
這里的數據統計的挺全乎的,包括了數據量、均值、方差、最大值、最小值等。
小編這里邪惡的想,如果在上中學考試的時候有這玩意,就再也不需要用手在草稿紙上一個一個去做重復的體力勞動了。
Pandas 還為我們提供了一個神奇的功能,「轉置數據」,就是把行列互換,示例如下:
# 轉置數據
print(df.T)
結果如下:
2020-01-01 2020-01-02 2020-01-03 2020-01-04 2020-01-05 2020-01-06
A 0.177499 1.067580 1.141218 0.920260 -0.729184 -0.480888
B -0.025693 1.592576 1.032333 -0.243247 -0.235706 -0.995325
C 0.182894 -0.010205 1.364477 0.196369 1.144007 -0.283726
D -1.123577 -0.349342 0.851630 -0.835655 -1.048619 0.428644
是不是很神奇,不過小編覺得並無什么實際用處。
我們在實際的應用場景中,經常會遇到排序的需求, Pandas 為我們提供了兩個方法, sort_index()
和 sort_values()
。
為了便於演示,小編這里重新構造了一個亂序的 DataFrame ,如下:
df1 = pd.DataFrame({'b' :[1,2,3,2],'a':[4,3,2,1],'c':[1,3,8,2]},index=[2,0,1,3])
print(df1)
結果如下:
b a c
2 1 4 1
0 2 3 3
1 3 2 8
3 2 1 2
可以看到,這個 df1 從索引和列名上看順序都是亂序的,接下來我們開始對這個 df1 進行排序,首先我們先使用 sort_values()
。
sort_values()
用途:既可以根據列數據,也可根據行數據排序。
注意:必須指定by參數,即必須指定哪幾行或哪幾列;無法根據 index 和 columns 排序(由 sort_index()
執行)
語法:DataFrame.sort_values(by, axis=0, ascending=True, inplace=False, kind='quicksort', na_position='last')
- axis:{0 or ‘index’, 1 or ‘columns’}, default 0,默認按照列排序,即縱向排序;如果為1,則是橫向排序。
- by:str or list of str;如果axis=0,那么by="列名";如果axis=1,那么by="行名"。
- ascending:布爾型,True則升序,如果by=['列名1','列名2'],則該參數可以是[True, False],即第一字段升序,第二個降序。
- inplace:布爾型,是否用排序后的數據框替換現有的數據框。
- kind:排序方法,{‘quicksort’, ‘mergesort’, ‘heapsort’}, default ‘quicksort’。似乎不用太關心。
- na_position:{‘first’, ‘last’}, default ‘last’,默認缺失值排在最后面。
按 b 列升序排序:
# 按 b 列升序排序
print(df1.sort_values(by='b'))
結果如下:
b a c
2 1 4 1
0 2 3 3
3 2 1 2
1 3 2 8
先按 b 列降序,再按 a 列升序排序:
# 先按 b 列降序,再按 a 列升序排序
print(df1.sort_values(by=['b','a'],axis=0,ascending=[False,True]))
結果如下:
b a c
1 3 2 8
3 2 1 2
0 2 3 3
2 1 4 1
按行 3 升序排列,必須指定 axis = 1
:
# 按行 3 升序排列,必須指定 axis = 1
print(df1.sort_values(by=3,axis=1))
結果如下:
a b c
2 4 1 1
0 3 2 3
1 2 3 8
3 1 2 2
按行 3 升序,行 0 降排列:
# 按行 3 升序,行 0 降排列
print(df1.sort_values(by=[3,0],axis=1,ascending=[True,False]))
結果如下:
a c b
2 4 1 1
0 3 3 2
1 2 8 3
3 1 2 2
sort_index()
用途:默認根據行標簽對所有行排序,或根據列標簽對所有列排序,或根據指定某列或某幾列對行排序。
注意:df.sort_index()
可以完成和 df.sort_values()
完全相同的功能,但 python 更推薦用只用 df.sort_index()
對 index 和 columns 排序,其他排序方式用 df.sort_values()
。
語法:DataFrame.sort_index(axis=0, level=None, ascending=True, inplace=False, kind='quicksort', na_position='last', sort_remaining=True, by=None)
- axis:0 按照行名排序;1 按照列名排序。
- level:默認 None ,否則按照給定的 level 順序排列。
- ascending:默認 True 升序排列; False 降序排列。
- inplace:默認False,否則排序之后的數據直接替換原來的數據框。
- kind:排序方法,{‘quicksort’, ‘mergesort’, ‘heapsort’}, default ‘quicksort’。似乎不用太關心。
- na_position:缺失值默認排在最后{"first","last"}。
- by:按照某一列或幾列數據進行排序,但是by參數貌似不建議使用。
默認按「行標簽」升序排列:
# 默認按「行標簽」升序排列
print(df1.sort_index())
結果如下:
b a c
0 2 3 3
1 3 2 8
2 1 4 1
3 2 1 2
按「列標簽」升序排列:
# 按「列標簽」升序排列
print(df1.sort_index(axis=1))
結果如下:
a b c
2 4 1 1
0 3 2 3
1 2 3 8
3 1 2 2
還有兩個按列排序的例子:
# 先按 b 列「降序」排列,因為 b 列中有相同值,相同值再按 a 列的「升序」排列
print(df1.sort_index(by=['b','a'],ascending=[False,True]))
# 先按 a 列「降序」排列,而 a 列中沒有相同值,因此這里按 b 列的「升序」排列不起作用。
print(df1.sort_index(by=['a','b'],ascending=[False,True]))
結果如下:
b a c
2 1 4 1
3 2 1 2
0 2 3 3
1 3 2 8
b a c
2 1 4 1
0 2 3 3
1 3 2 8
3 2 1 2
雖然正常排序,但是程序運行后也出現了警告,如下:
FutureWarning: by argument to sort_index is deprecated, please use .sort_values(by=...)
這個警告的意思是不推薦我們使用 sort_index()
使用 by 這個參數,推薦我們使用 sort_values()
這個方法。
示例代碼
老規矩,所有的示例代碼都會上傳至代碼管理倉庫 Github 和 Gitee 上,方便大家取用。