目錄
1. 介紹
- 2008年WesMcKinney開發出的庫
- 以NumPy爲基礎,借力NumPy模塊在計算方面性能高的優勢
- 專門用於數據挖掘的開源python庫
- 基於matplotlib,能夠簡便的畫圖
- 獨特的數據結構
1.1 爲什麼使用Pandas?
需求:創建一個符合正態分佈的10個股票5天的漲跌幅數據,使用 NumPy
創建示例代碼如下:
import numpy as np
stock_change = np.random.normal(0, 1, size=(10,5))
stock_change
上述代碼執行結果如下:
上述結果,很難看出來這個數據是用來描述什麼的,並且數據結構也不是十分的清晰。使用 Pandas
創建示例代碼如下:
import pandas as pd
import numpy as np
stock_change = np.random.normal(0, 1, size=(10,5))
# 1.構造行索引列表
stock_code = ["股票{}".format(str(i+1)) for i in range(stock_change2.shape[0])]
# 2.生成一個時間的序列 爲列索引
# start: "2020-05-01" 開始時間
# end: 結束日期
# periods: 時間天數 stock_change2.shape[1]==> 5天
# freq: 遞進單位,默認1天,'B'默認略過週末
# 注意: end和periods使用一個就可以了
stock_time = pd.date_range("2020-05-01", periods=stock_change2.shape[1], freq="B")
pd.DataFrame(stock_change, index=stock_code, columns=stock_time)
上述代碼執行結果如下:
從執行結果來看Pandas
讓數據更有意義的顯示。Pandas
學習的目的如下:
- 便捷的數據處理能力
- 讀取文件方便
- 封裝了Matplotlib、NumPy的畫圖和計算
1.2 DataFrame(對比二維數組)
DataFrame對象既有行索引,又有列索引:
- 行索引,表明不同行,橫向索引,叫index,0軸,axis=0
- 列索引,表名不同列,縱向索引,叫columns,1軸,axis=1
1.2.1 DataFrame的屬性
轉置,如下:
head():如果不補充參數,默認5行。填入參數N則顯示前N行,如下:
tail() 如果不補充參數,默認5行。填入參數N則顯示後N行,示例代碼如下:
1.2.2 DatatFrame索引的設置
修改行列索引值,示例代碼如下:
reset_index(drop=False),設置新的下標索引,drop: 默認爲False,不刪除原來索引,如果爲True,刪除原來的索引值。示例代碼如下:
以某列值設置爲新的索引,set_index(keys, drop=True)
- keys : 列索引名稱或者列索引名稱的列表
- drop : boolean, default True. 當做新的索引,刪除原來的列
示例代碼如下:
1.3 MultiIndex(對比三維數組)
打印剛纔的df的行索引結果:
多級或分層索引對象。index屬性:
- names:levels的名稱
- levels:每個level的元組值
1.4 Series結構(對比一維數組)
什麼是Series結構呢,我們直接看下面的圖:
series結構只有行索引。我們將之前的漲跌幅數據進行轉置,然後獲取股票 __0
的所有數據,示例代碼如下:
1.4.1 創建series
- 通過已有數據創建(指定內容,默認索引) 示例代碼如下:
- 指定索引 示例代碼如下:
- 通過字典數據創建 示例代碼如下:
- series獲取屬性和值 示例代碼如下:
2. 基本數據操作
爲了更好的理解這些基本操作,我們將讀取一個真實的股票數據。關於文件操作,後面在介紹,這裏只先用一下API,文件的獲取路徑如下:
鏈接:https://pan.baidu.com/s/1-3LnQSHyYeeFSEJ6roDY2w 密碼:40tm
讀取文件操作如下:
import pandas as pd
# 1.讀取文件
data = pd.read_csv("./data/stock_day.csv")
# 2.刪除一些列,讓數據更簡單些,再去做後面的操作
data = data.drop(["ma5","ma10","ma20","v_ma5","v_ma10","v_ma20"], axis=1)
數據展示結果如下:
2.1 索引操作
在 此處 我們已經學習過使用索引選取序列和切片選擇,Pandas
也支持類似的操作,也可以直接使用列名、行名稱,甚至組合使用。
2.1.1 直接使用行列索引(先列後行)
獲取2018-02-14
這天的 open
的結果,示例代碼如下:
data["open"]["2018-02-14"] # 先列後行 21.49
2.1.2 結合loc或者iloc使用索引
獲取從 2018-02-27 : 2018-02-14
,high
的結果,示例代碼如下:
# 獲取從'2018-02-27':'2018-02-14','high'的結果
data.loc['2018-02-27':'2018-02-14', "high"] # 使用loc:只能指定行列索引的名字
上述代碼執行結果爲:
獲取前10天數據的 open
和 high
列的結果,示例代碼如下:
data.iloc[:10, :2] # 使用iloc可以通過索引的下標去獲取
上述代碼執行結果爲:
2.1.3 組合索引
獲取行第1天到第4天,open/high/close
這三個指標的結果,示例代碼如下:
data.loc[data.index[:4], ["open","high","close"]]
上述代碼執行結果爲:
獲取行第2天到第5天,open/high/close/low
這四個指標的結果,示例代碼如下:
data.iloc[2:6, data.columns.get_indexer(["open","high","close","low"])]
上述代碼執行結果爲:
2.2 賦值操作
對DataFrame當中的 open
列進行重新賦值爲10
,示例代碼如下:
data["open"] = 10
上述代碼執行結果爲:
對DataFrame當中的 open
列進行重新賦值爲100
,示例代碼如下:
data.open = 100
上述代碼執行結果爲:
2.3 排序
排序有兩種形式,一種對於 索引
進行排序,一種對於 內容
進行排序。使用 df.sort_values(by=, ascending=),單個鍵排序,示例代碼如下:
# 按照漲跌幅大小進行排序 , 使用ascending指定按照大小排序
data.sort_values(by="p_change").head() # 默認升序
上述代碼執行結果爲:
多個鍵進行排序,示例代碼如下:
# 按照high進行排序,如果high值相同則比較close值
# ascending=True升序 =False降序
data.sort_values(by=["high", "close"], ascending=False).head()
上述代碼執行結果爲:
使用 df.sort_index
給索引進行排序,這個股票的日期索引原來是從大到小,現在重新排序,從小到大,示例代碼如下:
data.sort_index().head(3)
上述代碼執行結果爲:
使用 series.sort_values(ascending=True)
進行排序,series排序時,只有一列,不需要參數,示例代碼如下:
# 對high這一列的數據進行排序
# ascending=False: 降序排列
# data["high"] 返回的就是series
data["high"].sort_values(ascending=False).head()
上述代碼執行結果爲:
使用 series.sort_index()
進行排序,與df一致,示例代碼如下:
# 對high這一列的數據進行排序
data["high"].sort_index(ascending=True).head()
上述代碼執行結果爲:
3. DataFrame運算
爲了更好的理解這些基本操作,我們和上面一樣讀取一個真實的股票數據。關於文件操作,後面在介紹,這裏只先用一下API,文件的獲取路徑如下:
鏈接:https://pan.baidu.com/s/1-3LnQSHyYeeFSEJ6roDY2w 密碼:40tm
讀取文件操作如下:
import pandas as pd
# 1.讀取文件
data = pd.read_csv("./data/stock_day.csv")
# 2.刪除一些列,讓數據更簡單些,再去做後面的操作
data = data.drop(["ma5","ma10","ma20","v_ma5","v_ma10","v_ma20"], axis=1)
數據展示結果如下:
3.1 算術運算
add(other):比如進行數學運算加上具體的一個數字,示例代碼如下:
# 給open這一列的數據都加上10
data["open"].add(10).head()
# 或者是下面這種直接相加的方式 一般使用的比較少
data["open"] + 10
上述代碼執行結果爲:
sub(other):比如進行數學運算減去具體的一個數字,示例代碼如下:
data["open"].sub(10).head() # ==> data["open"] - 10
上述代碼執行結果爲:
如果想要得到每天的漲跌大小? 求出每天 close-open
價格差,示例代碼如下:
data["close"].sub(data["open"]).head() # 收盤價-開盤價
上述代碼執行結果爲:
3.2 邏輯運算
3.2.1 邏輯運算符號<、 >、|、 &
例如篩選 p_change > 2
的日期數據,示例代碼如下:
(data["p_change"] > 2).head() # 返回邏輯值
(data[data["p_change"]>2]).head() # 邏輯判斷的結果也可以作爲篩選的依據
上述代碼執行結果爲:
完成多個邏輯判斷, 篩選 p_change > 2
並且 open > 15
,示例代碼如下:
((data["p_change"] > 2) & (data["open"] > 15)).head(5)
data[(data["p_change"] > 2) & (data["open"] > 15)].head(5)
3.2.2 邏輯運算函數
query(expr):expr指的是查詢字符串。通過 query
使得剛纔的過程更加方便簡單。示例代碼如下:
data.query("p_change>2 & open > 15").head()
上述代碼執行結果爲:
isin(values):例如判斷 turnover
是否爲4.19
,2.39
,示例代碼如下:
data["turnover"].isin([4.19, 2.39]).head() # 返回邏輯值
data[data["turnover"].isin([4.19, 2.39])].head() # 返回符合條件的數據
上述代碼執行結果爲:
3.3 統計運算
describe():綜合分析,能夠直接得出很多統計結果 count/mean/std/min/max等。示例代碼如下:
data.describe()
上述代碼執行結果爲:
統計函數在 這裏 已經詳細介紹,以下演示 min(最小值),max(最大值),mean(平均值),median(中位數),var(方差),std(標準差),mode(衆數)的結果,示例代碼如下:
data.max() # 最大值
data.min() # 最小值
data.std(0) # 標準差
data.var() # 方差
# median(): 中位數
# 中位數爲將數據從小到大排列,在最中間的那個數爲中位數。如果沒有中間數,取中間兩個數的平均值。
df = pd.DataFrame({'COL1' : [2,3,4,5,4,2],
'COL2' : [0,1,2,3,4,2]})
df.median() # [2,3,4,5,4,2]==>[2,2,3,4,4,5]==>3+4/2==>3.5
data.idxmax() # 求出最大值的位置
data.idxmin() # 求出最小值的位置
注意:對於單個函數去進行統計的時候,座標軸還是按照這些默認爲 columns
(axis=0, default),如果要對行 index
需要指定(axis=1)。
3.4 累計統計函數
函數 | 作用 |
---|---|
cumsum | 計算前1/2/3/…/n個數的和 |
cummax | 計算前1/2/3/…/n個數的最大值 |
cummin | 計算前1/2/3/…/n個數的最小值 |
cumprod | 計算前1/2/3/…/n個數的積 |
那麼這些累計統計函數怎麼用?以上這些函數可以對 series
和 dataframe
操作。這裏我們按照時間的從前往後來進行累計,示例代碼如下:
# 排序之後,進行累計求和
data = data.sort_index()
# 對p_change進行求和
stock_rise = data["p_change"]
stock_rise.cumsum()
上述代碼執行結果爲:
那麼如何讓這個連續求和的結果更好的顯示呢?
3.5 自定義運算
apply(func, axis=0)
- func:自定義函數
- axis=0:默認是列,axis=1爲行進行運算
定義一個 對列 最大值-最小值
的函數,示例代碼如下:
data[["open", "close"]].apply(lambda x: x.max()-x.min(), axis=0)
上述代碼執行結果爲:
4. Pandas畫圖
語法格式如下:
DataFrame.plot(x=None, y=None, kind="line")
參數說明如下:
- x : label or position, default None
- y : label, position or list of label, positions, default None
- Allows plotting of one column versus another
- kind : str
- line : line plot (default)
- bar : vertical bar plot
- barh : horizontal bar plot
- hist : histogram
- pie : pie plot
- scatter : scatter plot
之前在 此處 已經詳細講解過上述常用的圖形,這裏的話不再詳細的用案例進行說明,在後續代碼中用到的時候在具體進行展示。
5. 文件讀取與存儲
我們的數據大部分存在於文件當中,所以 Pandas
會支持複雜的IO操作,Pandas
的API支持衆多的文件格式,如CSV、SQL、XLS、JSON、HDF5等。
5.1 CSV
5.1.1 read_csv
語法格式如下:
pd.read_csv(filepath_or_buffer, sep ="," )
參數說明如下:
- filepath_or_buffer:文件路徑
- usecols:指定讀取的列名,列表形式
讀取之前的股票的數據,示例代碼如下:
data = pd.read_csv("./data/stock_day.csv").head() # 讀取全部
# 讀取文件,並且指定只獲取"open", "close"指標
data = pd.read_csv("./data/stock_day.csv", usecols=["open", "close"]).head()
5.1.2 to_csv
語法格式如下:
DataFrame.to_csv(path_or_buf=None, sep=", ",columns=None,
header=True, index=True, mode="w", encoding=None)
參數說明如下:
- path_or_buf:string or file handle, default None
- sep:character, default
,
- columns:sequence, optional
- mode:
w
重寫,a
追加 - index:是否寫進行索引
- header:boolean or list of string, default True 是否寫進列索引值
保存 open
列的數據到csv文件中,示例代碼如下:
data[:10].to_csv("./data/amo.csv", columns=["open"])
上述代碼執行結果爲:
會發現將索引存入到文件當中,變成單獨的一列數據。如果需要刪除,可以指定index參數,刪除原來的文件,重新保存一次。示例代碼如下:
# index: 存儲不會將索引值變成一列數據
data[:10].to_csv("./data/amo2.csv", columns=["open"], index=False)
上述代碼執行結果爲:
5.2 HDF5
5.2.1 read_hdf 與 to_hdf
HDF5文件
的讀取和存儲需要指定一個鍵,值爲要存儲的DataFrame。從 h5
文件當中讀取數據,語法格式如下:
pandas.read_hdf(path_or_buf,key =None,** kwargs)
參數說明如下:
- path_or_buffer:文件路徑
- key:讀取的鍵
- return:Theselected object
DataFrame.to_hdf(path_or_buf, key, \kwargs)
5.2.2 案例
示例代碼如下:
# 讀取文件
day_eps_ttm = pd.read_hdf("./data/stock_data/day/day_eps_ttm.h5")
# 存儲文件
# 這個文件不能像csv一樣 直接打開觀看 只有先讀取出來在觀看
day_eps_ttm.to_hdf("./data/amo.h5", key="day_eps_ttm")
# 再次讀取的時候,需要指定鍵的名字
new_eps = pd.read_hdf("./data/amo.h5", key="day_eps_ttm")
new_eps.head()
上述代碼執行結果爲:
5.3 JSON
JSON是我們常用的一種數據交換格式,在前後端的交互,爬取數據的時候經常用到,也會在存儲的時候選擇這種格式。所以我們需要知道 Pandas
如何進行讀取和存儲JSON格式。
5.3.1 read_json
將JSON格式準換成默認的Pandas DataFrame格式,語法格式如下:
pandas.read_json(path_or_buf=None, orient=None, typ="frame", lines=False)
5.3.2 read_josn 案例
這裏使用一個新聞標題諷刺數據集,格式爲json。is_sarcastic:1諷刺的,否則爲0。headline:新聞報道的標題。article_link:鏈接到原始新聞文章。存儲格式爲:
{"article_link": "https://www.huffingtonpost.com/entry/versace-black-code_us_5861fbefe4b0de3a08f600d5", "headline": "former versace store clerk sues over secret 'black code' for minority shoppers", "is_sarcastic": 0}
{"article_link": "https://www.huffingtonpost.com/entry/roseanne-revival-review_us_5ab3a497e4b054d118e04365", "headline": "the 'roseanne' revival catches up to our thorny political mood, for better and worse", "is_sarcastic": 0}
讀取,orient
指定存儲的json格式,lines
指定按照行去變成一個樣本,示例代碼如下:
# orient指定存儲的json格式,lines指定按照行去變成一個樣本
json_read = pd.read_json("./data/Sarcasm_Headlines_Dataset.json", orient="records", lines=True)
json_read
結果爲:
5.3.3 to_json
將Pandas 對象存儲爲json格式,語法格式爲:
DataFrame.to_json(path_or_buf=None, orient=None, lines=False)
- path_or_buf=None:文件地址
- orient:存儲的json形式,{“split”,“records”,“index”,“columns”,“values”}
- lines:一個對象存儲爲一行
5.3.4 案例
示例代碼如下:
# 存儲文件
json_read.to_json("./data/amo.json", orient="records")
# 修改lines參數爲True
json_read.to_json("./data/amo2.json", orient="records", lines=True)
結果爲:
5.4 總結
優先選擇使用 HDF5
文件存儲,有以下原因:
HDF5
在存儲的時候支持壓縮,使用的方式是blosc
,這個是速度最快的也是Pandas
默認支持的- 使用壓縮可以提磁盤利用率,節省空間
HDF5
還是跨平臺的,可以輕鬆遷移到hadoop上面
筆者這篇博文寫完之後腦袋都炸掉了,Pandas
高級部分的操作會在 Python數據挖掘基礎(四):Pandas高級處理 中展示給大家,這篇博文太長,內容也比較多,並且在幾個小時內完成,難免出現錯誤,希望大家多多指教,編寫不易,大家手留餘香,感謝🙏。