本篇的 Pandas 格式說明,可以想像成在 Python 中如何操作 Excel 表格,比如如何建立 Excel 表格,如何存檔讀檔,如何選取欄或列,如何計算。
Pandas 貓熊
pandas 是 Python 一個重要的數據分析套件,於2009年開源出來,以 numpy 為基本資料型態,再度創造另一種高效易用的資料格式(DataFrame),可以快速進行資料分析。
Pandas 的基本資料格式叫 DataFrame,簡稱 df。DataFrame 這名詞不好理解,一般教學也說不清楚,其實很簡單,只要把 DataFrame 想成是一張 Excel 工作表格即可。
Pandas 可以讀取 Excel 檔案產生 DataFrame 資料格式,DataFrame 也可以將裏面的資料存成 Excel 檔。學習 Pandas 就好像在學習怎麼用 Python 操作 Excel。
使用前, 必需先 pip install pandas, 記注意, 有加 “s” 喔
補充說明
標準正態分佈(Standard normal distribution) : 又稱為u分佈,是以0為均值、以1為標準差的正態分佈,記為N(0,1)
np.random.randn(4,3,2) : 產生三維的正態分佈亂數, 維度可以隨便增加, 也可以是一維
Pandas的資料結構
Series : 類似 Excel 表格,但只有一個欄位。有自已的索引, 也可以自行命名。
DataFrame : 類似 Excel 表格,可以有欄位名,而每列資料錄可以有索引。
Series
Series 其實只有一個欄位,但有多筆資料。每筆資料都可以自訂索引,如下圖。
Series的用途,除了可以使用索引指定資料外,也可以使用標籤來指定,比如 s[0],或 s[‘地址’]。
預設索引
產生Series的方式,可以使用 pd.Series([]), 將list或np.array([])或字典 資料傳入, 如下示範list及array的使用方式。
import pandas as pd import numpy as np s1=pd.Series([1,2,3,4,5]) print(s1) print("s1[4]=%d " % s1[4]) s2=pd.Series(np.random.randint(0,3,5)) print(s2) 結果 : 0 1 1 2 2 3 3 4 4 5 dtype: int64 s1[4]=5 0 1 1 1 2 0 3 0 4 2 dtype: int32
自訂索引
Series 的自訂索引需在 Series 方法中加入 index 參數,index 可以為數字,也可以為字串。
當 index 為字串時,稱為標籤(Label),同時也會產生由 0 開始的索引。
當 index 為數字時,則只有索引,沒有標籤。
另外請注意一件事,index可以為list,亦可以為np 的陣列格式。
pd.Series([資料…], index=[索引…])
pd.Series([資料…], index=np.array([索引…]))
當有自訂標籤時,雖說也有索引,可以使用 s[4]這種寫法,但在新版的 Pandas 會出現如下警告
FutureWarning: Series.__getitem__ treating keys as positions is deprecated. In a future version, integer keys will always be treated as labels (consistent with DataFrame behavior). To access a value by position, use `ser.iloc[pos]`
這個警告是說 s[4] 這種寫法即將被拋棄,請改用 s.iloc[4],指定第 4 列的意思。
import pandas as pd index=['mercury','venus','earth','mars','jupiter','saturn','uranus','neptune','pluto'] planet=['水星','金星','地球','火星','木星','土星','天王星','海王星','冥王星'] s=pd.Series(planet, index=index) print(s) print(f"s.iloc[4]={s.iloc[4]}") print(f"s['jupiter']={s['jupiter']}") 結果 : mercury 水星 venus 金星 earth 地球 mars 火星 jupiter 木星 saturn 土星 uranus 天王星 neptune 海王星 pluto 冥王星 dtype: object s[4]=木星 s['jupiter']=木星
使用字典資料
Series 亦可使用字典產生,如下所示。
import pandas as pd d={'name':'Thomas', 'sex':'female', 'age':50, 'phone':'0989889123'} s=pd.Series(d) print(s) print('讀取值,可用如下三個方法,分別為索引,標籤,多索引list') print(f'索引 : {s[0]}') print(f'標籤 : {s["name"]}') print(f'多索引 : \n{s[[0,1,2]]}') print(f'多標籤 : \n{s[['name', 'sex']]} 結果 : name Thomas sex female age 50 phone 0989889123 dtype: object 讀取值,可用如下三個方法,分別為索引,標籤,多索引list 索引 : Thomas 標籤 : Thomas 多索引 : name Thomas sex female age 50 多標籤 : name Thomas sex female dtype: object
上述 s[[0,1,2]] 看起來怪怪的,請記得最外面的 “[]” 是包含索引的符號,而裏面的 “[]” 則是 List。
s[ [list] ]
DataFrame
把 DataFrame 是具有多個欄位,多筆資料的 Excel 表格,每個欄位需有欄位名稱,每列需有索引,如下圖的資料所示。
產生DataFrame的方式,有三個要注意,一是欄位名稱,二是每個欄的內容值,三是每列的索引。
共有三種方式可以產生 DataFrame 格式,可以想像成有三種方式建立 Excel 表格,詳述如下。
第一種方式
以行為主,將每行的資料集合在List中,再將每個List 加入以欄位名為 key 的字典
import pandas as pd data={ 'id': [1,2,3,4,5,6], 'name' : ['段譽','虛竹','喬峰','張三豐','張無忌','趙敏'], 'account' : ['thomas','kevin','eric','wind','kenneth','vivian'], 'password' : ['1234','2345','3456','4567','5678','6789'], 'sex' : ['M','M','M','M','M','F'], 'address': ['大理','少林','大寮','武當','光明頂','蒙古'] } df=pd.DataFrame(data) print(df) 結果 : id name account password sex address 0 1 段譽 thomas 1234 M 大理 1 2 虛竹 kevin 2345 M 少林 2 3 喬峰 eric 3456 M 大寮 3 4 張三豐 wind 4567 M 武當 4 5 張無忌 kenneth 5678 M 光明頂 5 6 趙敏 vivian 6789 F 蒙古
第二種方式
以列為主,每列以 {欄1:值1,欄2:值2, 欄3:值3} 的字典的方式形成,再將每列加入List中
import pandas as pd data=[] data.append({'id':1, 'name':'段譽', 'account':'thomas', 'password':'1234', 'sex':'M', 'address': '大理'}) data.append({'id':2, 'name':'虛竹', 'account':'kevin', 'password':'2345', 'sex':'M', 'address': '少林'}) data.append({'id':3, 'name':'喬峰', 'account':'eric', 'password':'3456', 'sex':'M', 'address': '大寮'}) data.append({'id':4, 'name':'張三豐', 'account':'wind', 'password':'4567', 'sex':'M', 'address': '武當'}) data.append({'id':5, 'name':'張無忌', 'account':'kenneth', 'password':'5678', 'sex':'M', 'address': '光明頂'}) data.append({'id':6, 'name':'趟敏', 'account':'vivian', 'password':'6789', 'sex':'F', 'address': '蒙古'}) df=pd.DataFrame(data) print(df)
第三種方式
也是以列為主,每列的資料集合在 List 中,再將每列加入 List 中。最後指定columns
import pandas as pd
data=[]
data.append([1,'段譽','thomas','1234','M','大理'])
data.append([2, '虛竹', 'kevin', '2345', 'M', '少林'])
data.append([3, '喬峰', 'eric', '3456', 'M', '大寮'])
data.append([4, '張三豐', 'wind', '4567', 'M', '武當'])
data.append([5, '張無忌', 'kenneth', '5678', 'M', '光明頂'])
data.append([6, '趟敏', 'vivian', '6789', 'F', '蒙古'])
cols=['id','name','account','password','sex','address']
df=pd.DataFrame(data=data, columns=cols)
print(df)
plotly_express 練習資料
plotly_express是一個用於資料分析和資料圖表化的套件,在後續的視覺化中會有詳細的說明。
plotly_express 提供了 gapminder 資料表,其格式就是DataFrame。裏面的資料記錄了世界各國的國名,洲別,每年的人口平均壽命,人口數,國別簡碼及國別代碼。
在使用此範例前,請先 pip install plotly-express
底下的代碼會因欄及列的資料太多而無法完整列出,所以會有 … 只列出部分資料
import plotly_express as px df = px.data.gapminder().query('year == 2007') print(df) 結果 : country continent year ... gdpPercap iso_alpha iso_num 11 Afghanistan Asia 2007 ... 974.580338 AFG 4 23 Albania Europe 2007 ... 5937.029526 ALB 8 35 Algeria Africa 2007 ... 6223.367465 DZA 12 47 Angola Africa 2007 ... 4797.231267 AGO 24 59 Argentina Americas 2007 ... 12779.379640 ARG 32 ... ... ... ... ... ... ... ... 1655 Vietnam Asia 2007 ... 2441.576404 VNM 704 1667 West Bank and Gaza Asia 2007 ... 3025.349798 PSE 275 1679 Yemen, Rep. Asia 2007 ... 2280.769906 YEM 887 1691 Zambia Africa 2007 ... 1271.211593 ZMB 894 1703 Zimbabwe Africa 2007 ... 469.709298 ZWE 716 [142 rows x 8 columns]
完美列印DataFrame
如果想要完整列出所有資料,需在 print(df) 之前更改四個參數如下。
import pandas as pd import plotly_express as px df=px.data.gapminder().query('year==2007') display=pd.options.display display.max_columns=None display.max_rows=None display.width=None display.max_colwidth=None print(df)
儲存成 Excel 檔
儲存成 Excel 檔,需先安裝 openpyxl 套件。
pip install openpyxl
底下代碼將把 px 取得的 df ,存成 gdp.xlsx 的 Excel 檔,其中的 index=None 表示 df 的 index 不會儲存到 Excel 檔案中。
import plotly_express as px df=px.data.gapminder().query('year==2007') df.to_excel("gdp.xlsx", sheet_name='Sheet1', index=None)
讀取 Excel 檔
讀取 Excel 檔,需先安裝 xlrd 套件。
pip install xlrd
底下代碼由 pd.read_excel 讀取 Excel 檔。
sheet_name=None 時,會把所有的工作表全都讀入,若沒有指定,則只讀取第一張工作表,若要指定某幾張工作表,可用如下方法指定
sheet_name=['202401', '202402']
index_col 是指定由第幾欄當作索引,如果沒有指定,則使用列數當索引。
keep_default_na = True 時,Excel 中沒有資料的儲存格將顯示 Nan。keep-default_na=False 時,沒有資料的儲存格將顯示空字串。
import pandas as pd df=pd.read_excel("gdp.xlsx", sheet_name='Sheet1',index_col=0, keep_default_na=False) print(df)
MySQL 轉 DataFrame
底下代碼說明如何取得資料庫的欄位名稱,再產生 DataFrame 格式。
import mysql.connector as mysql
import pandas as pd
conn=mysql.connect(host="ip", user="帳號", password="密碼", database="資料庫")
cursor=conn.cursor()
cursor.execute("select * from 台灣股市 order by 日期")
rs=cursor.fetchall()
#取得資料庫欄位名
descriptions=cursor.description
columns=[d[0] for d in descriptions]
df=pd.DataFrame(data=rs, columns=columns)
print(df)
結果:
id 日期 開盤 最高 最低 收盤
0 1 1999-01-05 6310.41 6310.41 6111.64 6152.43
1 2 1999-01-06 6082.02 6280.93 5988.06 6199.91
2 3 1999-01-07 6280.38 6409.55 6181.62 6404.31
3 4 1999-01-08 6371.34 6492.87 6371.34 6421.75
4 5 1999-01-11 6472.02 6492.90 6392.49 6406.99
iloc
iloc 可以同時指定列及欄。 iloc 只能使用數字 list 或數字切片。
列切片
df.iloc[:5] 指定前 5 列,跟 df.loc[:5] 是同樣的功能
import pandas as pd
import plotly_express as px
dis=pd.options.display
dis.max_columns=None
dis.max_rows=None
dis.width=None
dis.max_colwidth=None
df=px.data.gapminder()
df=df.query("year==2007")
print(df[:5])
print(df.iloc[:5])
結果:
country continent year lifeExp pop gdpPercap iso_alpha iso_num
11 Afghanistan Asia 2007 43.828 31889923 974.580338 AFG 4
23 Albania Europe 2007 76.423 3600523 5937.029526 ALB 8
35 Algeria Africa 2007 72.301 33333216 6223.367465 DZA 12
47 Angola Africa 2007 42.731 12420476 4797.231267 AGO 24
59 Argentina Americas 2007 75.320 40301927 12779.379640 ARG 32
country continent year lifeExp pop gdpPercap iso_alpha iso_num
11 Afghanistan Asia 2007 43.828 31889923 974.580338 AFG 4
23 Albania Europe 2007 76.423 3600523 5937.029526 ALB 8
35 Algeria Africa 2007 72.301 33333216 6223.367465 DZA 12
47 Angola Africa 2007 42.731 12420476 4797.231267 AGO 24
59 Argentina Americas 2007 75.320 40301927 12779.379640 ARG 32
指定特定列
df[] 只能使用切片,無法指定某幾列,但 df.iloc[[1,3,5,7]] 可以指定第 1,3,5,7 列
import pandas as pd
import plotly_express as px
dis=pd.options.display
dis.max_columns=None
dis.max_rows=None
dis.width=None
dis.max_colwidth=None
df=px.data.gapminder()
df=df.query("year==2007")
print(df.iloc[[1,3,5,7]])
結果:
country continent year lifeExp pop gdpPercap iso_alpha iso_num
23 Albania Europe 2007 76.423 3600523 5937.029526 ALB 8
47 Angola Africa 2007 42.731 12420476 4797.231267 AGO 24
71 Australia Oceania 2007 81.235 20434176 34435.367440 AUS 36
95 Bahrain Asia 2007 75.635 708573 29796.048340 BHR 48
欄切片
可以在列之後再加入欄切片,如下
import pandas as pd
import plotly_express as px
dis=pd.options.display
dis.max_columns=None
dis.max_rows=None
dis.width=None
dis.max_colwidth=None
df=px.data.gapminder()
df=df.query("year==2007")
print(df.iloc[:5,:4])
結果:
country continent year lifeExp
11 Afghanistan Asia 2007 43.828
23 Albania Europe 2007 76.423
35 Algeria Africa 2007 72.301
47 Angola Africa 2007 42.731
59 Argentina Americas 2007 75.320
指定某幾個欄位
換定的欄位只能使用數字編號,無法使用欄位名稱
import pandas as pd
import plotly_express as px
dis=pd.options.display
dis.max_columns=None
dis.max_rows=None
dis.width=None
dis.max_colwidth=None
df=px.data.gapminder()
df=df.query("year==2007")
print(df.iloc[:5,[0,1,4]])
結果:
country continent pop
11 Afghanistan Asia 31889923
23 Albania Europe 3600523
35 Algeria Africa 33333216
47 Angola Africa 12420476
59 Argentina Americas 40301927
指定儲存格
df.iloc[a, b] 可以指定第 a 列,第 b 欄的儲存格資料
import pandas as pd
import plotly_express as px
dis=pd.options.display
dis.max_columns=None
dis.max_rows=None
dis.width=None
dis.max_colwidth=None
df=px.data.gapminder()
df=df.query("year==2007")
print(df.iloc[0,0])
結果:
Afghanistan
讀取列 df[:] – 指定列數
loc 需指定已存在的索引編號,而 df[a:b] 則是指定第 a 列到第 b 列。如下代碼中列出前 10 列的資料
import pandas as pd
import plotly_express as px
dis=pd.options.display
dis.max_columns=None
dis.max_rows=None
dis.width=None
dis.max_colwidth=None
df=px.data.gapminder()
df=df.query("year==2007")
print(df[:10])
結果:
country continent year lifeExp pop gdpPercap iso_alpha iso_num
11 Afghanistan Asia 2007 43.828 31889923 974.580338 AFG 4
23 Albania Europe 2007 76.423 3600523 5937.029526 ALB 8
35 Algeria Africa 2007 72.301 33333216 6223.367465 DZA 12
47 Angola Africa 2007 42.731 12420476 4797.231267 AGO 24
59 Argentina Americas 2007 75.320 40301927 12779.379640 ARG 32
71 Australia Oceania 2007 81.235 20434176 34435.367440 AUS 36
83 Austria Europe 2007 79.829 8199783 36126.492700 AUT 40
95 Bahrain Asia 2007 75.635 708573 29796.048340 BHR 48
107 Bangladesh Asia 2007 64.062 150448339 1391.253792 BGD 50
119 Belgium Europe 2007 79.441 10392226 33692.605080 BEL 56
請注意,此方法無法使用 list 指定要那幾列,比如 df[0,3,5]則是錯誤的語法
讀取欄 df[[….]]
df[[…]] 則可以指定要讀取那幾欄,內層的 [] 需填入欄位名稱
import pandas as pd
import plotly_express as px
dis=pd.options.display
dis.max_columns=None
dis.max_rows=None
dis.width=None
dis.max_colwidth=None
df=px.data.gapminder()
df=df.query("year==2007")
print(df[['country','continent','pop']])
結果:
country continent pop
11 Afghanistan Asia 31889923
23 Albania Europe 3600523
35 Algeria Africa 33333216
47 Angola Africa 12420476
59 Argentina Americas 40301927
71 Australia Oceania 20434176
83 Austria Europe 8199783
95 Bahrain Asia 708573
107 Bangladesh Asia 150448339
........
列欄同時指定
比如只想列出前 5 列的 country, continent, pop 三欄的資料,可由如下二種方式指定
第一種
import pandas as pd
import plotly_express as px
dis=pd.options.display
dis.max_columns=None
dis.max_rows=None
dis.width=None
dis.max_colwidth=None
df=px.data.gapminder()
df=df.query("year==2007")
print(df[0:5][['country','continent','pop']])
結果:
country continent pop
11 Afghanistan Asia 31889923
23 Albania Europe 3600523
35 Algeria Africa 33333216
47 Angola Africa 12420476
59 Argentina Americas 40301927
第二種
import pandas as pd
import plotly_express as px
dis=pd.options.display
dis.max_columns=None
dis.max_rows=None
dis.width=None
dis.max_colwidth=None
df=px.data.gapminder()
df=df.query("year==2007")
print(df[['country','continent','pop']][0:5])
結果:
import pandas as pd
import plotly_express as px
dis=pd.options.display
dis.max_columns=None
dis.max_rows=None
dis.width=None
dis.max_colwidth=None
df=px.data.gapminder()
df=df.query("year==2007")
print(df[['country','continent','pop']][0:5])
df.values
df.values 會將所有列轉換成二維的 numpy 陣列,轉成的 numpy 格式 可以指定要列數,也可以使用切片。
import plotly_express as px
import pandas as pd
import numpy as np
dis=pd.options.display
dis.max_columns=None
dis.max_rows=None
dis.width=None
dis.max_colwidth=None
df=px.data.gapminder()
df=df.query("year==2007")
array=df.values
print(array)
結果:
[['Afghanistan' 'Asia' 2007 ... 974.5803384 'AFG' 4]
['Albania' 'Europe' 2007 ... 5937.029525999998 'ALB' 8]
['Algeria' 'Africa' 2007 ... 6223.367465 'DZA' 12]
...
['Yemen, Rep.' 'Asia' 2007 ... 2280.769906 'YEM' 887]
['Zambia' 'Africa' 2007 ... 1271.211593 'ZMB' 894]
['Zimbabwe' 'Africa' 2007 ... 469.70929810000007 'ZWE' 716]]
新增一列
DataFrame 無法插入新的一列,所以需先轉成 numpy格式,再使用 np.insert()插入新的一列,最後再轉回 DataFrame 格式。np.insert 參數說明如下
np.insert([值], 第幾列插入, value=[新列的值], axis=0)
底下代碼在 gapminder 最後新增一列,統計 2007 年全球總人口數。總人口數使用 df[[‘pop’]].sum() 進行計算。
import pandas as pd
import plotly_express as px
import numpy as np
dis=pd.options.display
dis.max_columns=None
dis.max_rows=None
dis.width=None
dis.max_colwidth=None
df=px.data.gapminder()
df=df.query("year==2007")
total=df[['pop']].sum().values[0]
#重設 index
df.index=list(range(df.shape[0]))
#新增一列
df=pd.DataFrame(np.insert(df.values, len(df), values=["total","","","",total,"","",""], axis=0))
print(df)
結果:
138 West Bank and Gaza Asia 2007 73.422 4018332 3025.349798 PSE 275
139 Yemen, Rep. Asia 2007 62.698 22211743 2280.769906 YEM 887
140 Zambia Africa 2007 42.384 11746035 1271.211593 ZMB 894
141 Zimbabwe Africa 2007 43.487 12311143 469.709298 ZWE 716
142 total 6251013179
df.loc 亦可在最後面新增一列,但無法在中間插入
import pandas as pd
import plotly_express as px
import numpy as np
dis=pd.options.display
dis.max_columns=None
dis.max_rows=None
dis.width=None
dis.max_colwidth=None
df=px.data.gapminder()
df=df.query("year==2007")
total=df[['pop']].sum().values[0]
#重設 index
df.index=list(range(df.shape[0]))
#新增一列
df.loc[len(df)]=["total","","","",total,"","",""]
print(df)
新增一欄
df.insert 可以新增一個欄位,參數說明如下
df.insert (插入的欄位, "欄位名稱", [值])
完整代碼如下
import pandas as pd import plotly_express as px import numpy as np dis=pd.options.display dis.max_columns=None dis.max_rows=None dis.width=None dis.max_colwidth=None df=px.data.gapminder() df=df.query("year==2007") total=df[['pop']].sum().values[0] #重設 index df.index=list(range(df.shape[0])) #新增一欄 df.insert(0,"欄名", total) print(df)
shift
df[[‘pop’]] = df.shift[[‘pop]].shift(1) 可以指定 pop 欄位往下偏移一列,如果是 shift(-1) 則往上偏移一列
import plotly_express as px
import pandas as pd
display=pd.options.display
display.max_columns=None
display.max_rows=None
display.width=None
display.max_colwidth=None
df=px.data.gapminder().query("year==2007").iloc[:10]
df[['pop']]=df[['pop']].shift(-1)
print(df)
結果:
country continent year lifeExp pop gdpPercap iso_alpha iso_num
11 Afghanistan Asia 2007 43.828 3600523.0 974.580338 AFG 4
23 Albania Europe 2007 76.423 33333216.0 5937.029526 ALB 8
35 Algeria Africa 2007 72.301 12420476.0 6223.367465 DZA 12
47 Angola Africa 2007 42.731 40301927.0 4797.231267 AGO 24
59 Argentina Americas 2007 75.320 20434176.0 12779.379640 ARG 32
71 Australia Oceania 2007 81.235 8199783.0 34435.367440 AUS 36
83 Austria Europe 2007 79.829 708573.0 36126.492700 AUT 40
95 Bahrain Asia 2007 75.635 150448339.0 29796.048340 BHR 48
107 Bangladesh Asia 2007 64.062 10392226.0 1391.253792 BGD 50
119 Belgium Europe 2007 79.441 NaN 33692.605080 BEL 56
dropna
上述的資料中,最底下一列有出現 NaN,使用 df = df.dropna() 則可以將含有 NaN 的列去除掉
import plotly_express as px import pandas as pd display=pd.options.display display.max_columns=None display.max_rows=None display.width=None display.max_colwidth=None df=px.data.gapminder().query("year==2007").iloc[:10] df[['pop']]=df[['pop']].shift(-1) df=df.dropna() print(df) 結果 : country continent year lifeExp pop gdpPercap iso_alpha iso_num 11 Afghanistan Asia 2007 43.828 3600523.0 974.580338 AFG 4 23 Albania Europe 2007 76.423 33333216.0 5937.029526 ALB 8 35 Algeria Africa 2007 72.301 12420476.0 6223.367465 DZA 12 47 Angola Africa 2007 42.731 40301927.0 4797.231267 AGO 24 59 Argentina Americas 2007 75.320 20434176.0 12779.379640 ARG 32 71 Australia Oceania 2007 81.235 8199783.0 34435.367440 AUS 36 83 Austria Europe 2007 79.829 708573.0 36126.492700 AUT 40 95 Bahrain Asia 2007 75.635 150448339.0 29796.048340 BHR 48 107 Bangladesh Asia 2007 64.062 10392226.0 1391.253792 BGD 50
todo
資料庫格式
此篇為補充說明,上述的 df.values 是將 df 轉成 numpy 格式。
但若是由資料庫讀入的 rs 資料,格式為 [(…..), (……), ……],每筆資料都是 tuple 組成,然後多筆資料組成 list。如果想要把 tuple 改成 list,也就是改成 [[……], [……],……],就要使用如下代碼
import mysql.connector as mysql
conn=mysql.connect(host="mahaljsp.ddns.net", user="lcc", password="lcc0507", database="cloud")
cursor=conn.cursor()
cursor.execute("select * from 台灣股市 order by 日期")
rs=cursor.fetchall()
rs=[list(r) for r in rs]
print(rs)
結果:
[[1, datetime.date(1999, 1, 5), 6310.41, 6310.41, 6111.64, 6152.43], [2, datetime.date(1999, 1, 6), 6082.02, 6280.93, 5988.06, 6199.91],.......]
產生日期格式
pd.date_range()可以產生第一個參數開始的日期格式. 如下, 每列使用日期當索引, 欄位名為 ABCD四欄位
dates=pd.date_range("2019/08/01", periods=6) df0=pd.DataFrame(np.random.randn(6,4), index=dates, columns=list('ABCD')) print(df0)
df.describe
describe可以求出每一欄位的數量, 平均值, 標準差…等資訊
df0.describe() 及 mem_df.describe()分別如下
其它功能
df.head(2) : 印前二個
df.tail(2) : 印後二個
df.transpose() : 轉置
df.sort_index(axis=1, ascending=True) :
axis=0: 對索引進行排序, axis=1 : 對欄位名稱排序
ascending : False 遞減
import pandas as pd import numpy as np dates=pd.period_range('2020/01/01', '2020/01/10') rng=np.random.RandomState(1) df=pd.DataFrame(rng.randn(len(dates),4), index=dates, columns=list('ABCD')) print(df.sort_index(axis=0, ascending=False)) 結果 : A B C D 2020-01-10 -1.117310 0.234416 1.659802 0.742044 2020-01-09 -0.687173 -0.845206 -0.671246 -0.012665 2020-01-08 -0.267888 0.530355 -0.691661 -0.396754 2020-01-07 0.900856 -0.683728 -0.122890 -0.935769 2020-01-06 -1.100619 1.144724 0.901591 0.502494 2020-01-05 -0.172428 -0.877858 0.042214 0.582815 2020-01-04 -0.322417 -0.384054 1.133769 -1.099891 2020-01-03 0.319039 -0.249370 1.462108 -2.060141 2020-01-02 0.865408 -2.301539 1.744812 -0.761207 2020-01-01 1.624345 -0.611756 -0.528172 -1.072969
import pandas as pd import numpy as np dates=pd.period_range('2020/01/01', '2020/01/10') rng=np.random.RandomState(1) df=pd.DataFrame(rng.randn(len(dates),4), index=dates, columns=list('ABCD')) print(df.sort_index(axis=1, ascending=False)) 結果 : D C B A 2020-01-01 -1.072969 -0.528172 -0.611756 1.624345 2020-01-02 -0.761207 1.744812 -2.301539 0.865408 2020-01-03 -2.060141 1.462108 -0.249370 0.319039 2020-01-04 -1.099891 1.133769 -0.384054 -0.322417 2020-01-05 0.582815 0.042214 -0.877858 -0.172428 2020-01-06 0.502494 0.901591 1.144724 -1.100619 2020-01-07 -0.935769 -0.122890 -0.683728 0.900856 2020-01-08 -0.396754 -0.691661 0.530355 -0.267888 2020-01-09 -0.012665 -0.671246 -0.845206 -0.687173 2020-01-10 0.742044 1.659802 0.234416 -1.117310
df.sort_values(by=’D’,ascending=False) : 使用D欄位遞減排序
df.index : 印出每列的索引
df.columns : 印出欄位名稱
df.values : 傳回每一列的list
df.shape : 傳回df的列數及行數
讀取儲存格資料
譊取行列的語法,採用 df.iloc[列, 行] ,列與行採用 “,” 隔開。多列或多行使用 “:” 隔開,如下語法
df.iloc[啟始列:結束列, 啟始行:結束行]
1. df.iloc[列, 行] : df.iloc[0,0]讀取第0列, 第0行的資料。請注意,索引編號由 0開始
2. df.iloc[列, [行, 行, 行]] : df.iloc[2,[0,1,2]] 讀取第2列, 0,1,2 行的資料. 使用values取出
3. df.iloc[列, :] : df.iloc[2,:] 讀取第2列所有行的資料. “:”代表所有行(或列). 使用values取出
3. df.iloc[:, 5] : df.iloc[:, 5] 讀取所有列第5列的資料. 使用values取出
import plotly_express as px df = px.data.gapminder().query('year == 2007') print('DataFrame 前 3 列資料') for i in range(3): print(df.values[i]) print() print('列印第0列第0,1,2欄') row=df.iloc[0,[0,1,2]] for c in row: print(f'{c} ', end='') print('\n') row=df.iloc[0,:] print('第0列所有資料 :\n',row, '\n') print('list :', list(row)) print('dict :', dict(row)) print('\n') column=df.iloc[0:3,1] print('第1行前3列的資料 :\n',column, '\n') print(column) print('list :', list(column)) print('dict :', dict(column)) print('\n') 結果: DataFrame 前 3 列資料 ['Afghanistan' 'Asia' 2007 43.828 31889923 974.5803384 'AFG' 4] ['Albania' 'Europe' 2007 76.423 3600523 5937.029525999998 'ALB' 8] ['Algeria' 'Africa' 2007 72.301 33333216 6223.367465 'DZA' 12] 列印第0列第0,1,2欄 Afghanistan Asia 2007 第0列所有資料 : country Afghanistan continent Asia year 2007 lifeExp 43.828 pop 31889923 gdpPercap 974.580338 iso_alpha AFG iso_num 4 Name: 11, dtype: object list : ['Afghanistan', 'Asia', 2007, 43.828, 31889923, 974.5803384, 'AFG', 4] dict : {'country': 'Afghanistan', 'continent': 'Asia', 'year': 2007, 'lifeExp': 43.828, 'pop': 31889923, 'gdpPercap': 974.5803384, 'iso_alpha': 'AFG', 'iso_num': 4} 第1行前3列的資料 : 11 Asia 23 Europe 35 Africa Name: continent, dtype: object 11 Asia 23 Europe 35 Africa Name: continent, dtype: object list : ['Asia', 'Europe', 'Africa'] dict : {11: 'Asia', 23: 'Europe', 35: 'Africa'}
查詢功能
#設定搜尋條件 df=(df[df['country']=='Taiwan']) #選取要列印的欄位 print(df[['country', 'year']]) #新增欄位 df['abb']=d['country'].apply(lambda x:x[:3]) #計算某欄位總合 print(df[df['year']==2007][['pop']].sum()) #計算多欄位的平均 print(df[df['year']==2007][['lifeExp', 'gdpPercap']].mean())
DataFrame視覺化
DataFrame 也可以視覺化製作圖表。但DataFrame使用matplotlib製作圖表,所以必需先
pip install matplotlib。
底下df[[list]] 中,list裏的欄位除了要有繪制圖表的資料外,也要包含要顯示在 x 軸及 y 軸的資料。list裏的資料如果是數字才會繪制,文字的部份就不會繪制。
x軸的標籤若要使用國別,可以在plot參數中加入 x=’country’
import plotly_express as px import pylab as plt df=px.data.gapminder().query("year==2007 and continent=='Asia'") print(df.columns) df[['country','pop']].plot(kind='bar', x='country') plt.show()
讀取列 loc – 指定索引編號
底下的東西,本人覺的是 Pandas 在執行這個專案時未考慮到的多餘作法,只不過網路上還是有人用這些語法撰寫,所以還是記錄一下。
loc 可以指定索引編號讀取列,但傳入的索引 list 必需是索引編號存在的數字,比如經過 df.query(“year=2007”) 查詢後,索引編號只剩下 11, 23, 35, 47…..等1000多列。而0,1,2,….等編號都不在了。所以只能使用 df.loc[[11,23,35,47]],若使用 df.loc[[0,1,2,3,4,5]] 是錯誤的寫法。
另外也可以使用切片功能,比如 df.loc[0:50] 則列出索引編號 0~49 的列,不存在的索引則會去除。請注意 loc傳回的是 DataFrame格式。
import pandas as pd
import plotly_express as px
dis=pd.options.display
dis.max_columns=None
dis.max_rows=None
dis.width=None
dis.max_colwidth=None
df=px.data.gapminder()
df=df.query("year==2007")
print(df.loc[[11,23,35]])
print(df.loc[:50])
結果:
country continent year lifeExp pop gdpPercap iso_alpha iso_num
11 Afghanistan Asia 2007 43.828 31889923 974.580338 AFG 4
23 Albania Europe 2007 76.423 3600523 5937.029526 ALB 8
35 Algeria Africa 2007 72.301 33333216 6223.367465 DZA 12
country continent year lifeExp pop gdpPercap iso_alpha iso_num
11 Afghanistan Asia 2007 43.828 31889923 974.580338 AFG 4
23 Albania Europe 2007 76.423 3600523 5937.029526 ALB 8
35 Algeria Africa 2007 72.301 33333216 6223.367465 DZA 12
47 Angola Africa 2007 42.731 12420476 4797.231267 AGO 24