一.Pandas簡介
Pandas(Python Data Analysis Library)基於Numpy構建,讓基於Numpy的應用更簡單,被廣泛應用於金融行業,流行的數據分析工具
二.Pandas安裝
由於Pandas是python的第三方庫,需要另外安裝
pip3 install pandas
三.Pandas的數據結構
Pandas主要有兩種數據結構:
- 系列(
Series
) - 數據幀(
DataFrame
)
系列(Series
)是能夠保存任何類型的數據(整數,字符串,浮點數,Python對象等)的一維標記數組。軸標簽統稱為索引。
數據幀(DataFrame)是二維數據結構,即數據以行和列的表格方式排列。
數據幀(DataFrame)的功能特點:
- 潛在的列是不同的類型
- 大小可變
- 標記軸(行和列)
- 可以對行和列執行算術運算
四.各個數據結構示例
1.Series
1)創建Series
# coding:utf-8
import pandas as pd
obj = pd.Series([1, 3, 24, 23, 8])
print(obj)
print("--"*10)
print(obj.values)
print("--"*10)
print(obj.index)
print("--"*10)
print(obj[3])
0 1 1 3 2 24 3 23 4 8 dtype: int64 -------------------- [ 1 3 24 23 8] -------------------- RangeIndex(start=0, stop=5, step=1) -------------------- 23
2)自定義index,定義索引后,原有位置索引依然可以使用
obj = pd.Series([1, 3, 24, 23, 8],index=list("abcde")) print(obj) print("--"*10) print(obj.values) print("--"*10) print(obj.index) print("--"*10) print(obj[3],obj["d"])
a 1 b 3 c 24 d 23 e 8 dtype: int64 -------------------- [ 1 3 24 23 8] -------------------- Index(['a', 'b', 'c', 'd', 'e'], dtype='object') -------------------- 23 23
也可以重新索引,如果某個索引值當前不存在,就引入缺失值“NaN”,
obj = pd.Series([1, 3, 24, 23, 8],index=list("abcde")) obj2=obj.reindex(['b','c','d','f','g']) print(obj2) print("--"*10) print("obj:{}".format(obj.values)) print("obj2:{}".format(obj2.values)) print("--"*10) print(obj2.index) print("--"*10) print(obj2[3],obj2["d"])
b 3.0 c 24.0 d 23.0 f NaN g NaN dtype: float64 -------------------- obj:[ 1 3 24 23 8] obj2:[ 3. 24. 23. nan nan] -------------------- Index(['b', 'c', 'd', 'f', 'g'], dtype='object') -------------------- nan 23.0
對於缺失值,可以填充其他值
obj = pd.Series([1, 3, 24, 23, 8],index=list("abcde")) obj2=obj.reindex(['b','c','d','f','g'],fill_value=0) print(obj2) print("--"*10) print("obj:{}".format(obj.values)) print("obj2:{}".format(obj2.values)) print("--"*10) print(obj2.index) print("--"*10) print(obj2[3],obj2["d"])
b 3 c 24 d 23 f 0 g 0 dtype: int64 -------------------- obj:[ 1 3 24 23 8] obj2:[ 3 24 23 0 0] -------------------- Index(['b', 'c', 'd', 'f', 'g'], dtype='object') -------------------- 0 23
3)使用字典創建Series,字典key會作為series的索引
dic={'calvin':7,'kobe':24,'mj':23,'kd':35} print(pd.Series(dic)) ##### calvin 7 kd 35 kobe 24 mj 23 dtype: int64
2.DataFrame
在所有操作之前當然要先import必要的pandas庫,因為pandas常與numpy一起配合使用,所以也一起import吧。對於numpy這個包后面再來寫,先導入,看代碼,開始這次的重點
1)直接創建,可以直接使用pandas的DataFrame函數創建,比如接下來我們隨機創建一個4*4的DataFrame。上面提到過,DataFrame是二維數據結構
# coding:utf-8 import pandas as pd import numpy as np df1=pd.DataFrame(np.random.randn(4,4),index=list('ABCD'),columns=list('ABCD')) print("=="*50) print(df1) print("=="*50) print(df1.ndim) print("=="*50) print(df1.size) print("=="*50) print(df1.shape)
結果:
==================================================================================================== A B C D A -0.077428 1.117524 0.595675 -0.247774 B 0.734320 2.117861 1.531927 -0.485774 C 1.126023 -0.640626 0.755659 -0.651486 D -0.008357 -0.582401 -0.908435 0.225568 ==================================================================================================== 2 #ndim查看DataFrame的"軸",軸為2,即為2維 ==================================================================================================== 16 #size查看DataFrame的數據量,16個數據 ==================================================================================================== (4, 4) #shape查看DataFrame的類型,即4行4列
其中第一個參數是存放在DataFrame里的數據,第二個參數index就是之前說的行名(或者應該叫索引?),第三個參數columns是之前說的列名。
后兩個參數可以使用list輸入,但是注意,這個list的長度要和DataFrame的大小匹配,不然會報錯。當然,這兩個參數是可選的,你可以選擇不設置。
而且發現,這兩個list是可以一樣的,但是每行每列的名字在index或columns里要是唯一的。
2)使用字典創建,
dic1 = { 'name': ['小明', '小紅', '狗蛋', '鐵柱'], 'age': [17, 20, 5, 40], 'gender': ['男', '女', '女', '男'] } df3 = pd.DataFrame(dic1,) print(df3) #### age gender name 0 17 男 小明 1 20 女 小紅 2 5 女 狗蛋 3 40 男 鐵柱
3.DataFrame查看與篩選數據
3.1 查看列的數據類型,dtypes
df3 = pd.DataFrame(dic1,) print(df3.dtypes) ########## age int64 gender object name object dtype: object
3.2 查看DataFrame的頭尾head(),tail()默認都是5行
df4=pd.DataFrame(np.random.randn(6,6)) print(df4.head()) print("--"*50) print(df4.tail(2)) ####### 0 1 2 3 4 5 0 1.343776 -1.279881 -1.181201 -0.396298 -1.125743 -0.611221 1 0.948905 -0.345690 -1.790776 1.020443 -1.254210 -2.217274 2 -0.528329 -0.972449 -0.851321 0.260332 -0.189709 -1.215085 3 -0.520668 1.463702 1.161444 0.734592 -0.766386 0.911954 4 -0.091497 2.277969 -0.596919 1.223075 0.701117 1.179839 ---------------------------------------------------------------------------------------------------- 0 1 2 3 4 5 4 -0.091497 2.277969 -0.596919 1.223075 0.701117 1.179839 5 1.274698 0.056263 -0.244694 0.841284 -0.596790 -1.340147
3.3 查看DataFrame的行名與列名df1.index、df3.columns
df1 = pd.DataFrame(np.random.randn(4, 4), index=list('abcd'), columns=list('ABCD')) print(df1) print("--"*50) print(df1.index) print(df1.columns) ###### A B C D a 0.554493 0.952188 1.506555 -0.618873 b 0.255190 0.357644 0.002479 -0.307104 c -0.283515 0.220664 -0.458655 0.830601 d -0.608960 -0.301327 0.400476 0.118921 ---------------------------------------------------------------------------------------------------- Index(['a', 'b', 'c', 'd'], dtype='object') Index(['A', 'B', 'C', 'D'], dtype='object')
3.4 查看DataFrame的值, values。返回的是一個數組。
dic1 = { 'name': ['小明', '小紅', '狗蛋', '鐵柱'], 'age': [17, 20, 5, 40], 'gender': ['男', '女', '女', '男'] } df3 = pd.DataFrame(dic1,) print(df3) print("--"*50) print(df3.values) ##### age gender name 0 17 男 小明 1 20 女 小紅 2 5 女 狗蛋 3 40 男 鐵柱 ---------------------------------------------------------------------------------------------------- [[17 '男' '小明'] [20 '女' '小紅'] [5 '女' '狗蛋'] [40 '男' '鐵柱']]
查看某一列的數據
dic1 = { 'name': ['小明', '小紅', '狗蛋', '鐵柱'], 'age': [17, 20, 5, 40], 'gender': ['男', '女', '女', '男'] } df3 = pd.DataFrame(dic1,) print(df3) print("--"*30) print(df3["name"]) print("--"*30) print(df3["name"].values) ###### age gender name 0 17 男 小明 1 20 女 小紅 2 5 女 狗蛋 3 40 男 鐵柱 ------------------------------------------------------------ 0 小明 1 小紅 2 狗蛋 3 鐵柱 Name: name, dtype: object ------------------------------------------------------------ ['小明' '小紅' '狗蛋' '鐵柱']
使用loc或者iloc查看數據值(但是好像只能根據行來查看?)。區別是loc是根據行名,iloc是根據數字索引(也就是行號)。
df1 = pd.DataFrame(np.random.randn(4, 4), index=list('abcd'), columns=list('ABCD')) print(df1.loc["a"]) ------- A -0.224071 B 0.183044 C 0.769312 D 0.700409 Name: a, dtype: float64
或者這樣。
df1 = pd.DataFrame(np.random.randn(4, 4), index=list('abcd'), columns=list('ABCD')) print(df1.iloc[0]) ------ A -0.193388 B -0.552667 C 0.368871 D -1.143332 Name: a, dtype: float64
3.5 查看行列數,shape查看行列數,參數為0表示查看行數,參數為1表示查看列數。
dic1 = { 'name': ['小明', '小紅', '狗蛋', '鐵柱'], 'age': [17, 20, 5, 40], 'gender': ['男', '女', '女', '男'] } df3 = pd.DataFrame(dic1, ) print(df3) print("--" * 50) print("行數:{},列數:{}".format(df3.shape[0], df3.shape[1])) print("類型:%s * %s" % df3.shape) ###### age gender name 0 17 男 小明 1 20 女 小紅 2 5 女 狗蛋 3 40 男 鐵柱 ---------------------------------------------------------------------------------------------------- 行數:4,列數:3 類型:4 * 3
3.5 小結。
data = {'name': ['calvin', 'kobe', 'michale', 'durant', 'james'], 'age': [29, 40, 56, 30, 34], 'height': [1.70, 1.98, 1.98, 2.06, 2.03]} # 從字典創建DataFrame data2 = [['a', 1], ['b', 2], ['c', 3]] # 從列表創建DataFrame data3 = {'one': pd.Series([1, 2, 3], index=['a', 'b', 'c']), 'two': pd.Series([1, 2, 3, 4], index=['a', 'b', 'c', 'd'])} # 從系列的字典來創建DataFrame dd = pd.DataFrame(data3) df = pd.DataFrame(data2, columns=['name', 'age']) # 加入列標簽 dd['three'] = pd.Series([10, 20, 30], index=['a', 'b', 'c']) # 增加列
print(pd.DataFrame(data)) ## age height name 0 29 1.70 calvin 1 40 1.98 kobe 2 56 1.98 michale 3 30 2.06 durant 4 34 2.03 james
print(df) ### name age 0 a 1 1 b 2 2 c 3
print(dd) ### one two three a 1.0 1 10.0 b 2.0 2 20.0 c 3.0 3 30.0 d NaN 4 NaN
print(dd['one']) # 列選擇 ### **************************************** a 1.0 b 2.0 c 3.0 d NaN Name: one, dtype: float64 **************************************** print(dd.loc['b']) # 行選擇(標簽選擇) **************************************** one 2.0 two 2.0 three 20.0 Name: b, dtype: float64 **************************************** print(dd.iloc[1]) # 行選擇(按整數位置選擇) **************************************** one 2.0 two 2.0 three 20.0 Name: b, dtype: float64 **************************************** print(dd[0:2]) # 行切片 **************************************** one two three a 1.0 1 10.0 b 2.0 2 20.0 ****************************************
下表列出了DataFrame構造函數所能接受的各種數據:
類型 |
說明 |
二維ndarray |
數據矩陣,還可以傳入行標和列標 |
由數組、列表或元組組成的字典 |
每個序列會變成DataFrame的一列。所有序列的長度必須相同 |
Numpy的結構化/記錄數組 |
類似於“由數組組成的字典” |
由Series組成的字典 |
每個Series會成為一列。如果沒有顯示指定索引,則各Series的索引會被合並成結果的行索引 |
由字典組成的字典 |
各內層字典會成為一列。鍵會被合並成結果的行索引,跟“由Series組成的字典”的情況一樣 |
字典或Series的列表 |
各項將會成為DataFrame的一行。字典鍵或Series索引的並集將會成為DataFrame的列標 |
由列表或元組組成的列表 |
類似於“二維ndarray” |
另一個DataFrame |
該DataFrame的索引將會被沿用,除非顯式指定了其他索引 |
Numpy的MaskedArray |
類似於“二維ndarray”的情況,只是掩碼值在結果DataFrame會變成NA/缺失值 |
五.讀取Excel文件&CSV文件
新建一個測試用的Excel,命名為
test.xlsx
並加入一些數據,放入到pycharm工程目錄下,數據如下圖:
import pandas as pd data=pd.read_excel("test.xlsx") print(data.head(3)) #讀取前三行數據 ======================================== Date Open Hight Low Close Adj Close Volume 0 2019-10-09 50.123456 75.123456 20.123456 33.123456 43.123456 45.123456 1 2019-10-10 51.123456 76.123456 21.123456 34.123456 44.123456 46.123456 2 2019-10-11 52.123456 77.123456 22.123456 35.123456 45.123456 47.123456 ======================================== print(data.tail(3)) #讀取后三行數據 ======================================== Date Open Hight ... Close Adj Close Volume 23 2019-11-01 73.123456 98.123456 ... 56.123456 66.123456 68.123456 24 2019-11-02 74.123456 99.123456 ... 57.123456 67.123456 69.123456 25 2019-11-03 75.123456 100.123456 ... 58.123456 68.123456 70.123456 [3 rows x 7 columns] ======================================== print(data.describe()) #數據概要統計 ======================================== Open Hight Low Close Adj Close Volume count 26.000000 26.000000 26.000000 26.000000 26.000000 26.000000 mean 62.623456 87.623456 32.623456 45.623456 55.623456 57.623456 std 7.648529 7.648529 7.648529 7.648529 7.648529 7.648529 min 50.123456 75.123456 20.123456 33.123456 43.123456 45.123456 25% 56.373456 81.373456 26.373456 39.373456 49.373456 51.373456 50% 62.623456 87.623456 32.623456 45.623456 55.623456 57.623456 75% 68.873456 93.873456 38.873456 51.873456 61.873456 63.873456 max 75.123456 100.123456 45.123456 58.123456 68.123456 70.123456 ========================================
import pandas as pd import matplotlib.pyplot as plt data=pd.read_excel("test.xlsx") #使用日期做索引 dates=pd.to_datetime(data['Date']) df=data.set_index(dates) df.drop('Date',1,inplace=True) df['Open'].plot() plt.show() #顯示圖片
#訪問某列 print(df['Close']) #切片,獲取指定的行 print(df['2018-08-08':'2018-08-18']) #索引切片 print(df.loc['2018-08-09',['Open','Close']]) #兩個維度切片 print(df.loc['2018-08-09','Open']) #查看2018-08-09這個日期的Open值 print(df.loc['2018-08-02':'2018-08-06','Close']) #查看2018-08-02到2018-08-06之間的Close值 print(df.loc['2018-08-04':'2018-08-08',['Open','Close']]) #查看2018-08-02到2018-08-06之間的Open值和Close值 #位置切片 print(df.iloc[0,:]) #查看第一條數據 print(df.iloc[-5:,:])#獲取倒數五條數據 print(df.iloc[-20:-10:4]) #步長為4,獲取倒數20行到倒數10行的數據 print(df.iloc[0,0]) #獲取第一條的第一個數據 print(df.at[dates[0],'Close']) #獲取第一個日期的Close值 print(df[df['Open']>60]) #篩選數據,獲取Open值大於60的數據 df['Fake']=pd.Series(np.random.randn(len(df)),index=dates) #增加一列數據 print(df) df2=df.copy() #拷貝一個df2 df2[df2<0]=np.nan #小於0的全部設為NAN print(df2) print(df.mean()) #每一列的平均值 print(df.mean(1)) #每一行的平均值 print(df.groupby(by=df.index.year).mean()) #以年分組,求各年份的平均值 print(df.sort_values(by='Open',ascending=False)) #默認升序排序,ascending=False設置降序排列 #批量迭代讀取csv data2=pd.read_csv('test.csv',iterator=True,chunksize=10000,usecols=['date']) print(data2.get_chunk(4)) #獲取前四行的數據 print(data2) #顯示一串字符串 <pandas.io.parsers.TextFileReader object at 0x004CC490> for i in data2: #迭代讀取csv的數據 print(i)