Pandas是一個(gè)強(qiáng)大的分析結(jié)構(gòu)化數(shù)據(jù)的工具集;它的使用基礎(chǔ)是Numpy(提供高性能的矩陣運(yùn)算);用于數(shù)據(jù)挖掘和數(shù)據(jù)分析,同時(shí)也提供數(shù)據(jù)清洗功能。
0. Pandas數(shù)據(jù)結(jié)構(gòu)分析
0.1 Series
Series是一個(gè)類似一維數(shù)組的對象,他能夠保存任何類型的數(shù)據(jù),由左面的索引和右面的數(shù)據(jù)兩部分組成。
0.1.1 語法:
pandas.Series(data=None, index=None, dtype=None, name=None, copy=False, fastpath=False)
部分參數(shù):
- data:數(shù)據(jù)
- index:索引
0.1.2 使用:
代碼:
import pandas as pd
# 創(chuàng)建Series對象
data = pd.Series(data=[2, 3, 4, 5])
print("data為:\n", data)
# 更改索引
data.index = [1, 2, 3, 4]
print("\n更改索引后的data為:\n", data)
# 由字典創(chuàng)建
info = {"name": "zz", "class": 'ji3'}
data = pd.Series(data=info)
print("\n由數(shù)據(jù)創(chuàng)建的data為:\n", data)
# 字符串索引
print("\ndata[1]=", data[1])
# 字符串拼接
print("\n字符串后加ha:\n", data + "ha")
輸出:
data為:
0 2
1 3
2 4
3 5
dtype: int64
更改索引后的data為:
1 2
2 3
3 4
4 5
dtype: int64
由數(shù)據(jù)創(chuàng)建的data為:
name zz
class ji3
dtype: object
data[1]= ji3
字符串后加ha:
name zzha
class ji3ha
dtype: object
0.2 DataFrame
DataFrame是一個(gè)類似于二維數(shù)組或表格,他每列的數(shù)據(jù)可以是不同的數(shù)據(jù)類型。
0.2.1 語法
pandas.DataFrame(data=None, index=None, columns=None, dtype=None, copy=False)
部分參數(shù)說明:
- index:表示行標(biāo)簽,若不設(shè)置參數(shù)則默認(rèn)自動創(chuàng)建一個(gè)從0~N的整數(shù)索引
- columns:列標(biāo)簽
0.2.2 使用:
代碼:
import pandas as pd
# 創(chuàng)建DataFrame
df = pd.DataFrame([[56, 68, 11, 55], [57, 68, 11, 33], [57, 65, 11, 33]])
print("df=\n", df)
# 創(chuàng)建帶行索引的DataFrame
df = pd.DataFrame([[56, 68, 11, 55], [57, 68, 11, 33], [57, 65, 11, 33]],
index=["zz", "wcc", "wyf"])
print("\ndf(帶行索引)=\n", df)
# 創(chuàng)建帶行列索引的DataFrame
df = pd.DataFrame([[56, 68, 11, 55], [57, 68, 11, 33], [57, 65, 11, 33]],
index=["zz", "wcc", "wyf"],
columns=["語文", "數(shù)學(xué)", "英語", "物理"])
print("\ndf(帶行列索引)=\n", df)
# 添加數(shù)據(jù)
df["物理"] = [12, 22, 32]
print("\ndf(添加列)=\n", df)
# 刪除列
del df["語文"]
print("\ndf(刪除列)=\n", df)
輸出:
df=
0 1 2 3
0 56 68 11 55
1 57 68 11 33
2 57 65 11 33
df(帶行索引)=
0 1 2 3
zz 56 68 11 55
wcc 57 68 11 33
wyf 57 65 11 33
df(帶行列索引)=
語文 數(shù)學(xué) 英語 物理
zz 56 68 11 55
wcc 57 68 11 33
wyf 57 65 11 33
df(添加列)=
語文 數(shù)學(xué) 英語 物理
zz 56 68 11 12
wcc 57 68 11 22
wyf 57 65 11 32
df(刪除列)=
數(shù)學(xué) 英語 物理
zz 68 11 12
wcc 68 11 22
wyf 65 11 32
1. Pandas索引操作及高級索引
1.1 對象索引
索引對象無法進(jìn)行單獨(dú)修改,保證數(shù)據(jù)安全,但是可以整體設(shè)置,例如:
import pandas as pd
data = pd.DataFrame([[66, 77, 98, 121], [75, 32, 111, 32], [11, 33, 23, 56]],
index=['wcc', 'wyf', 'yxy'],
columns=['跳高', '跳遠(yuǎn)', '競走', '跑圈'])
print(data)
# data.index[1] = 'zz' # 錯(cuò)誤使用
data.index = ['zz', 'wyf', 'yxy']
print("修改后:", data)
如果輸入代碼第6
行代碼會報(bào)錯(cuò):
TypeError: Index(...) must be called with a collection of some kind, 'zz' was passed
正確的代碼輸出為:
跳高 跳遠(yuǎn) 競走 跑圈
wcc 66 77 98 121
wyf 75 32 111 32
yxy 11 33 23 56
修改后: 跳高 跳遠(yuǎn) 競走 跑圈
zz 66 77 98 121
wyf 75 32 111 32
yxy 11 33 23 56
?擴(kuò)展層次化索引
分層/多級索引在處理復(fù)雜的數(shù)據(jù)分析和數(shù)據(jù)操作方面為開發(fā)者奠定了基礎(chǔ),尤其是在處理高緯度數(shù)據(jù)處理上。本質(zhì)上,它使您能夠在較低維度的數(shù)據(jù)結(jié)構(gòu)(如 Series
(一維)和DataFrame
(二維))中存儲和操作任意維數(shù)的數(shù)據(jù)。
下面這個(gè)例子將演示如何由DataFrame
對象創(chuàng)建層次化索引:
import pandas as pd
data = pd.DataFrame({
"Country": ["Us", "China", "China", "China"],
"Province": ["Washington", "Shandong", "Beijing", "Tianjin"],
"People": ["zz", "bill", "wcc", "wyf"]
})
print(data.set_index(["Country", "Province"]))
輸出為:
People
Country Province
Us Washington zz
China Shandong bill
Beijing wcc
Tianjin wyf
1.2 重置索引
Pandas中提供了一個(gè)重要方法reindex()
,該方法的作用是對原索引和新索引進(jìn)行匹配,也就是說,新索引含有原索引的數(shù)據(jù),而原索引數(shù)據(jù)按照新索引排序。如果新索引中沒有原索引數(shù)據(jù),那么程序不僅不會報(bào)錯(cuò)而且會添加新索引并將值填充為NaN
或者使用fill_values()
填充其他值。
1.2.1 reindex()
方法
語法:
DataFrame.reindex(labels=None,index=None,columns=None,axis=None,method=None,copy=True,level=None,fill_value=nan,limit=None,tolerance=None)
部分參數(shù)解釋:
-
index
:用作索引的新序列 method
:插值填充方式-
fill_value
:引入缺失值時(shí)使用的替代值 -
limit
:前向或后向填充時(shí)的最大填充量
前向/后向填充可以使用reindex()
方法中的methon='ffill'
(后向填充)、mothon='bfill'
(前向填充),也可以使用ffill()
或bfill()
方法,建議使用reindex().ffill()
/reindex().bfill()
代碼:
import pandas as pd
data = pd.Series([1,5,3,8,4], index=['b', 'e', 'a', 'd', 'g'])
print(data.reindex(['a', 'b', 'c', 'd', 'e', 'f', 'g'],
fill_value=6)) # 填充缺失值為6
print(data.reindex(['a', 'b', 'c', 'd', 'e', 'f', 'g']).bfill()) # 后向填充
print(data.reindex(['a', 'b', 'c', 'd', 'e', 'f', 'g']).ffill()) # 前向填充
輸出:
a 3
b 1
c 6
d 8
e 5
f 6
g 4
dtype: int64
a 3.0
b 1.0
c 8.0
d 8.0
e 5.0
f 4.0
g 4.0
dtype: float64
a 3.0
b 1.0
c 1.0
d 8.0
e 5.0
f 5.0
g 4.0
dtype: float64
1.3 索引操作
1.3.1 Series索引
基礎(chǔ)索引
Series有關(guān)索引與Numpy相似,對于Series索引既可通過位置也可通過index
(索引名稱)獲取:
import pandas as pd
data = pd.Series(range(1, 6), index=['a', 'b', 'c', 'd', 'e'])
print("位于2位置的元素為:", data[2])
print("索引名稱為'c'的元素為:", data['c'])
輸出為:
位于2位置的元素為: 3
索引名稱為'c'的元素為: 3
Series切片索引
總結(jié):
由于Series的索引有兩種形式,因此切片也有兩種形式但是有一點(diǎn)點(diǎn)區(qū)別:
- 位置索引:包括起始位置不包括終止位置
- 名稱索引:包括起始位置和終止位置
位置索引:
語法:
pandas[start:stop:step]
代碼:
import pandas as pd
dataSlice = pd.Series(range(1, 10),
index=['a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i'])
# 位置索引的幾種形式
print("位置在[2,6)之間的元素為:")
print(dataSlice[2:6])
print("位置在[6,2)之間的元素(逆序)為:")
print(dataSlice[6:2:-1])
print("位置在[6,2)之間(步長為2)的元素(逆序)為:")
print(dataSlice[6:2:-2])
輸出:
位置在[2,6)之間的元素為:
c 3
d 4
e 5
f 6
dtype: int64
位置在[6,2)之間的元素(逆序)為:
g 7
f 6
e 5
d 4
dtype: int64
位置在[6,2)之間(步長為2)的元素(逆序)為:
g 7
e 5
dtype: int64
名稱索引:
語法:
pandas[start:stop:step]
代碼:
import pandas as pd
dataSlice = pd.Series(range(1, 10),
index=['a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i'])
print("名稱在[c,g]之間的元素為:")
print(dataSlice['c':'g'])
print("名稱在[g,c]之間的元素(逆序)為:")
print(dataSlice['g':'c':-1])
print("名稱在[c,g]之間(步長為2)的元素(逆序)為:")
print(dataSlice['g':'c':-2])
輸出:
名稱在[c,g]之間的元素為:
c 3
d 4
e 5
f 6
g 7
dtype: int64
名稱在[g,c]之間的元素(逆序)為:
g 7
f 6
e 5
d 4
c 3
dtype: int64
名稱在[c,g]之間(步長為2)的元素(逆序)為:
g 7
e 5
c 3
dtype: int64
不連續(xù)索引
代碼:
import pandas as pd
dataSlice = pd.Series(range(1, 10),
index=['a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i'])
print(dataSlice[[1, 2, 5]])
print(dataSlice[['a', 'd', 'e']])
輸出:
b 2
c 3
f 6
dtype: int64
a 1
d 4
e 5
dtype: int64
布爾型索引
返回符合表達(dá)式的變量。
代碼:
import pandas as pd
dataSlice = pd.Series(range(1, 10),
index=['a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i'])
print(dataSlice[dataSlice > 6])
輸出:
g 7
h 8
i 9
dtype: int64
1.3.2 DataFrame索引
基礎(chǔ)索引
語法:
DataFrame[index][column]
? 基礎(chǔ)語法只能為先行后列,index
僅可使用切片,column
可以為切片或元素,因此當(dāng)DataFrame索引只有一個(gè)對象時(shí)使用名稱索引會直接匹配列即column
參數(shù)。
代碼:
import numpy as np
import pandas as pd
data = pd.DataFrame(np.arange(12).reshape(3, 4), columns=['a', 'b', 'c', 'd'])
# 兩參數(shù)索引
print("兩參數(shù)索引:")
print(data[1:2]['a'])
# 不連續(xù)Series對象索引
print("不連續(xù)Series對象索引:")
print(data[['a', 'c']])
# 使用切片進(jìn)行行索引
print("使用切片進(jìn)行行索引:")
print(data[:2])
# 獲取b列的數(shù)據(jù)
print("b列的數(shù)據(jù):")
print(data['b'])
# 行列序號相同時(shí)的單參數(shù)名稱索引
print("行列序號相同時(shí)的單參數(shù)名稱索引:")
data_2 = pd.DataFrame(np.arange(12).reshape(3, 4))
print("行號:", data_2.index)
print("列號:", data_2.columns)
print(data_2[2])
輸出:
兩參數(shù)索引:
1 4
Name: a, dtype: int32
不連續(xù)Series對象索引:
a c
0 0 2
1 4 6
2 8 10
使用切片進(jìn)行行索引:
a b c d
0 0 1 2 3
1 4 5 6 7
b列的數(shù)據(jù):
0 1
1 5
2 9
Name: b, dtype: int32
行列序號相同時(shí)的單參數(shù)名稱索引:
行號: RangeIndex(start=0, stop=3, step=1)
列號: RangeIndex(start=0, stop=4, step=1)
0 2
1 6
2 10
Name: 2, dtype: int32
高級索引
**
Pandas庫中提供了操作索引的方法來訪問數(shù)據(jù),具體包括:
- loc:基于標(biāo)簽索引(索引名稱,如a、b等),用于按標(biāo)簽選取數(shù)據(jù),當(dāng)執(zhí)行切片操作時(shí)既包含起始索引也包括結(jié)束索引。
- iloc:基于位置索引(整數(shù)索引,從0到length-1),用于按位置選取數(shù)據(jù)。當(dāng)執(zhí)行切片操作時(shí),只包含起始索引不包括結(jié)束索引。
ilog
主要使用整數(shù)來索引數(shù)據(jù)而不能使用字符標(biāo)簽來索引數(shù)據(jù),而loc
只能使用字符標(biāo)簽來索引數(shù)據(jù)而不能使用整數(shù)來索引數(shù)據(jù)。
loc
代碼:
import numpy as np
import pandas as pd
data = pd.DataFrame(np.arange(16).reshape(4, 4), columns=['a', 'b', 'c', 'd'])
print(data.loc[:, ['a', 'c']])
輸出:
a c
0 0 2
1 4 6
2 8 10
3 12 14
iloc
代碼:
import numpy as np
import pandas as pd
data = pd.DataFrame(np.arange(16).reshape(4, 4), columns=['a', 'b', 'c', 'd'])
print(data.iloc[:, [2, 0]])
輸出:
c a
0 2 0
1 6 4
2 10 8
3 14 12
loc
和iloc
函數(shù)第一個(gè)參數(shù)是行索引,例如:
import numpy as np
import pandas as pd
data = pd.DataFrame(np.arange(16).reshape(4, 4), columns=['a', 'b', 'c', 'd'])
print(data.iloc[1:3, [2, 0]])
輸出為:
c a
1 6 4
2 10 8
2. 算術(shù)運(yùn)算與數(shù)據(jù)對齊
在Pandas中Series對象進(jìn)行運(yùn)算時(shí),索引長度不同的Series對象進(jìn)行運(yùn)算缺失值處會填充為NaN
,如果希望使用NaN
填充缺失數(shù)據(jù)可以使用方法中的fill_value
參數(shù),例子以加法為例:
import pandas as pd
data = pd.Series([1, 4, 5])
data_2 = pd.Series([0, 7, 6, 8, 4])
print(data.add(data_2, fill_value=0))
輸出為:
0 1.0
1 11.0
2 11.0
3 8.0
4 4.0
dtype: float64
即:
3. 數(shù)據(jù)排序
3.1 按索引排序
3.1.1 語法
sort_index(axis=0,level=None,ascending=True,inplace=False,kind='quicksort',na_position='last',sort_remaining=True)
部分參數(shù)說明:
-
axis
:軸索引,0
表示index
(行),1
表示columns
(列) -
level
:若不為None
,則對指定索引級別的值進(jìn)行排序 -
ascending
:是否升序排序,默認(rèn)True
表示升序 -
inplace
:默認(rèn)為False
表示對數(shù)據(jù)表進(jìn)行排序不創(chuàng)建新實(shí)例 -
kind
:選擇排序算法
3.1.2 Series對象
直接排序
代碼:
import pandas as pd
data = pd.Series(range(6),index=[1,5,7,6,3,2])
print(data.sort_index())
輸出:
1 0
2 5
3 4
5 1
6 3
7 2
dtype: int64
降序排序
代碼:
import pandas as pd
data = pd.Series(range(6),index=[1,5,7,6,3,2])
print(data.sort_index(ascending=False))
輸出:
7 2
6 3
5 1
3 4
2 5
1 0
dtype: int64
3.1.3 DataFrame對象
按行索引升序排序
代碼:
import numpy as np
import pandas as pd
data = pd.DataFrame(np.arange(12).reshape(3,4),index=[5,1,2],columns=[8,2,1,3])
print(data.sort_index())
輸出:
8 2 1 3
1 4 5 6 7
2 8 9 10 11
5 0 1 2 3
按列索引降序排序
代碼:
import numpy as np
import pandas as pd
data = pd.DataFrame(np.arange(12).reshape(3, 4),
index=[5, 1, 2],
columns=[8, 2, 1, 3])
print(data.sort_index(axis=1, ascending=False))
輸出:
8 3 2 1
5 0 3 1 2
1 4 7 5 6
2 8 11 9 10
3.2 按值排序
3.2.1 語法
sort_values(by,axis=0,level=None,ascending=True,inplace=False,kind='quicksort',na_position='last')
部分參數(shù)說明:
-
by
:排序的列 -
axis
:軸索引,0
表示index
(行),1
表示columns
(列) -
level
:若不為None
,則對指定索引級別的值進(jìn)行排序 -
ascending
:是否升序排序,默認(rèn)True
表示升序 -
na_position
:如果設(shè)置為first
則會將NaN
值放在開頭;如果設(shè)置為last
則會將NaN
值放在最后。
3.2.2 Series對象
升序排序
代碼:
import numpy as np
import pandas as pd
data = pd.Series([4, np.nan, 6, np.nan, -2, 2])
print(data.sort_values())
輸出:
4 -2.0
5 2.0
0 4.0
2 6.0
1 NaN
3 NaN
dtype: float64
3.2.3 DataFrame對象
列索引排序
代碼:
import pandas as pd
data = pd.DataFrame([[1, 2, 5, 4], [2, 5, 9, 1], [1, 5, 9, 11], [2, 8, 1, 2]])
print(data.sort_values(by=2))
輸出:
0 1 2 3
3 2 8 1 2
0 1 2 5 4
1 2 5 9 1
2 1 5 9 11
4. 統(tǒng)計(jì)計(jì)算與描述
4.1 常用的統(tǒng)計(jì)計(jì)算
函數(shù)名稱 | 說明 | 函數(shù)名稱 | 說明 |
---|---|---|---|
sum |
和 | std |
標(biāo)準(zhǔn)差 |
mean |
平均值 | skew |
三階矩 |
median |
中位數(shù) | kurt |
四階矩 |
max |
最大值 | min |
最小值 |
idxmax |
最大索引值 | idxmin |
最小索引值 |
count |
非NaN 值的個(gè)數(shù) |
head |
獲取前N個(gè)值 |
var |
方差 | cumsum |
累積和 |
cummin |
累積最小值 | cummax |
累積最大值 |
cumprod |
累計(jì)積 | describe |
列計(jì)算匯總 |
示例代碼
import numpy as np
import pandas as pd
data = pd.DataFrame(np.arange(12).reshape(3,4),columns=['a','b','c','d'])
print("原數(shù)據(jù):")
print(data)
print("求和:")
print(data.sum(axis=1))
print("求中位數(shù):")
print(data.median())
輸出:
原數(shù)據(jù):
a b c d
0 0 1 2 3
1 4 5 6 7
2 8 9 10 11
求和:
0 6
1 22
2 38
dtype: int64
求中位數(shù):
a 4.0
b 5.0
c 6.0
d 7.0
dtype: float64
4.2 describe
統(tǒng)計(jì)描述
4.2.1 函數(shù)語法
describe(percentiles=None,include=None,exclude=None)
常用參數(shù)含義:
-
percentiles
:輸出中包含的百分?jǐn)?shù),位于[0,1]之間,如果不設(shè)置參數(shù)則默認(rèn)為[0.25,0.5,0.75],返回25%,50%,75%分位數(shù)。 -
include
、exclude
:指定返回結(jié)果的形式
4.2.2 示例代碼
import numpy as np
import pandas as pd
data = pd.DataFrame(np.arange(12).reshape(3,4),columns=['a','b','c','d'])
print(data.describe())
輸出:
a b c d
count 3.0 3.0 3.0 3.0
mean 4.0 5.0 6.0 7.0
std 4.0 4.0 4.0 4.0
min 0.0 1.0 2.0 3.0
25% 2.0 3.0 4.0 5.0
50% 4.0 5.0 6.0 7.0
參照數(shù)組:
a b c d
0 0 1 2 3
1 4 5 6 7
2 8 9 10 11
5.層次化索引
5.1 認(rèn)識層次化索引
在一個(gè)軸方向上有多層索引。如圖:
Series和DataFrame均可以實(shí)現(xiàn)層次化索引,最常見的方式是在構(gòu)造方法的index參數(shù)中傳入一個(gè)嵌套列表。
5.1.1 Series
對象層次化索引
例如:
import pandas as pd
mulitindex_series = pd.Series(
[12462, 1546, 1234, 123, 5456, 5554, 33213, 2124],
index=[['河北省', '河北省', '河北省', '河北省', '河南省', '河南省', '河南省', '河南省'],
['石家莊市', '唐山市', '邯鄲市', '秦皇島市', '鄭州市', '開封市', '洛陽市', '新鄉(xiāng)市']])
print(mulitindex_series)
輸出為:
河北省 石家莊市 12462
唐山市 1546
邯鄲市 1234
秦皇島市 123
河南省 鄭州市 5456
開封市 5554
洛陽市 33213
新鄉(xiāng)市 2124
dtype: int64
5.1.2 DataFrame
對象層次化索引
例如:
import pandas as pd
mulitindex_DataFrame = pd.DataFrame(
{'占地面積': [12462, 1546, 1234, 123, 5456, 5554, 33213, 2124]},
index=[['河北省', '河北省', '河北省', '河北省', '河南省', '河南省', '河南省', '河南省'],
['石家莊市', '唐山市', '邯鄲市', '秦皇島市', '鄭州市', '開封市', '洛陽市', '新鄉(xiāng)市']])
print(mulitindex_DataFrame)
輸出:
占地面積
河北省 石家莊市 12462
唐山市 1546
邯鄲市 1234
秦皇島市 123
河南省 鄭州市 5456
開封市 5554
洛陽市 33213
新鄉(xiāng)市 2124
5.2 常用方法
總述:
層次化索引除了直接創(chuàng)建之外還可以通過MultiIndex
類的方法構(gòu)建層次化索引,這個(gè)類提供了三種創(chuàng)建層次化索引的方法:
-
MultiIndex.from_tuples()
:將元組列表轉(zhuǎn)換為MultiIndex
-
MultiIndex.from_arrays()
:將數(shù)組列表轉(zhuǎn)換為MultiIndex
-
MultiIndex.from_product()
:從多個(gè)集合的笛卡爾乘積中創(chuàng)建MultiIndex
from_tuples()
from_tuples()
方法可以將包含若干個(gè)元組的列表轉(zhuǎn)換為MultiIndex
對象,其中元組的第一個(gè)元素作為外層索引,第二個(gè)元素作為內(nèi)層索引,例如:
import pandas as pd
from pandas import MultiIndex
list_tuples = [('A', 'A1'), ('A', 'A2'), ('B', 'B1'), ('B', 'B2'), ('B', 'B3')]
multi_index = MultiIndex.from_tuples(tuples=list_tuples,
names=['外層索引', '內(nèi)層索引'])
value = [[1,2,3],[4,5,6],[7,8,9],[10,11,12],[13,14,15]]
df_indexs = pd.DataFrame(data=value,index=multi_index)
print(df_indexs)
輸出為:
0 1 2
外層索引 內(nèi)層索引
A A1 1 2 3
A2 4 5 6
B B1 7 8 9
B2 10 11 12
B3 13 14 15
from_arrays()
from_arrays()
方法是將數(shù)組列表轉(zhuǎn)換為MultiIndex
對象,其中嵌套的第一個(gè)列表將作為外層索引,嵌套的第二個(gè)列表將作為內(nèi)層索引。例如:
import pandas as pd
from pandas import MultiIndex
multi_array = MultiIndex.from_arrays(
arrays=[['A', 'A', 'B', 'B', 'B'], ['A1', 'A2', 'B1', 'B2', 'B3']])
value = [[1, 2, 3], [4, 5, 6], [7, 8, 9], [10, 11, 12], [13, 14, 15]]
df_indexs = pd.DataFrame(data=value, index=multi_array)
print(df_indexs)
輸出:
0 1 2
A A1 1 2 3
A2 4 5 6
B B1 7 8 9
B2 10 11 12
B3 13 14 15
from_product()
from_product()
方法表示從多個(gè)集合的笛卡爾乘積創(chuàng)建一個(gè)MultiIndex
對象。
什么是笛卡爾乘積?
笛卡爾積的符號化為:
A×B={(x,y)|x∈A∧y∈B}
例如,A={a,b}, B={0,1,2},則
A×B={(a, 0), (a, 1), (a, 2), (b, 0), (b, 1), (b, 2)}
B×A={(0, a), (0, b), (1, a), (1, b), (2, a), (2, b)}
例如:
import numpy as np
import pandas as pd
from pandas import MultiIndex
numbers = [0, 1, 2]
colors = ['green', 'purple']
multi_product = MultiIndex.from_product(iterables=[numbers, colors],
names=['number', 'color'])
value = np.array([[7, 5], [6, 6], [3, 1], [5, 5], [4, 5], [5, 3]])
df_product = pd.DataFrame(data=value, index=multi_product)
print(df_product)
輸出為:
0 1
number color
0 green 7 5
purple 6 6
1 green 3 1
purple 5 5
2 green 4 5
purple 5 3
5.3 層次化索引操作
任務(wù)一:錄入下面層次化對象
代碼:
import pandas as pd
ser_obj = pd.Series([78, 65, 44, 98, 66, 100, 97, 68],
index=[['機(jī)械', '機(jī)械', '機(jī)械', '信息', '信息', '工程', '工程', '工程'],
['張三', '李四', '王二', '宋天', '汪全', '寒月', '天使', '葛藤']])
輸出:
機(jī)械 張三 78
李四 65
王二 44
信息 宋天 98
汪全 66
工程 寒月 100
天使 97
葛藤 68
dtype: int64
任務(wù)二:篩選外層索引為機(jī)械的數(shù)據(jù)
代碼:
print(ser_obj['機(jī)械'])
輸出:
張三 78
李四 65
王二 44
dtype: int64
任務(wù)三:篩選內(nèi)層索引為李四的數(shù)據(jù)
代碼:
print(ser_obj[:, '李四'])
輸出:
機(jī)械 65
dtype: int64
任務(wù)四:交換分層順序
代碼:
print(ser_obj.swaplevel())
輸出:
張三 機(jī)械 78
李四 機(jī)械 65
王二 機(jī)械 44
宋天 信息 98
汪全 信息 66
寒月 工程 100
天使 工程 97
葛藤 工程 68
dtype: int64
任務(wù)五:索引排序
sort_index()
語法sort_index(axis=0,level=None,ascending=True,inplace=False,kind='quicksort',na_position='last',sort_remaining=True,by=None)
by
:表示按指定的值排序ascending
:布爾值,表示是否升序排列,默認(rèn)為True
代碼:
print(ser_obj.sort_index())
輸出:
信息 宋天 98
汪全 66
工程 天使 97
寒月 100
葛藤 68
機(jī)械 張三 78
李四 65
王二 44
dtype: int64
層次化索引中先對外層索引進(jìn)行排序再對每一個(gè)外層索引的內(nèi)層索引進(jìn)行排序。如果需要對值進(jìn)行排序可以使用sort_values()
函數(shù)。
任務(wù)六:錄入下面的層次化對象并對num
列進(jìn)行降序排序
代碼:
import pandas as pd
dat_obj = pd.DataFrame(
{
"model": [
'CPU', 'GPU', 'FLASH', 'SSD', 'HDD', 'USB', 'TYPE-C', 'MIC-USB',
'DRIVE'
],
"num": [80, 152, 113, 354, 1, 231, 35, 12, 7]
},
index=[['A', 'A', 'A', 'B', 'B', 'C', 'C', 'C', 'C'],
[1, 2, 4, 3, 5, 1, 5, 8, 1]])
print(dat_obj.sort_values(by='num', ascending=False))
輸出:
model num
B 3 SSD 354
C 1 USB 231
A 2 GPU 152
4 FLASH 113
1 CPU 80
C 5 TYPE-C 35
8 MIC-USB 12
1 DRIVE 7
B 5 HDD 1
6. 數(shù)據(jù)的讀寫
6.1 讀寫文本文件
6.1.1 寫入文本文件函數(shù)to_csv()
函數(shù)語法:
詳細(xì)參數(shù)請查看官方文檔:DataFrame.to_csv()
to_csv(path_or_buf=None,sep=',',na_rep='',float_format=None,columns=None,header=True,index=True,index_label=None,mode='w',……)
-
path_or_buf
:文件路徑 -
index
:默認(rèn)為True
,若設(shè)為False
,則將不會顯示索引 -
sep
:分隔符,默認(rèn)用","隔開
代碼:
import pandas as pd
data_csv = pd.DataFrame(
{
"model": [
'CPU', 'GPU', 'FLASH', 'SSD', 'HDD', 'USB', 'TYPE-C', 'MIC-USB',
'DRIVE'
],
"num": [80, 152, 113, 354, 1, 231, 35, 12, 7]
},
index=[['A', 'A', 'A', 'B', 'B', 'C', 'C', 'C', 'C'],
[1, 2, 4, 3, 5, 1, 5, 8, 1]])
data_csv.to_csv('./test.csv', index=True)
這種方法同樣可以輸出擴(kuò)展名為
txt
的文件。
輸出:
在本目錄會生成一個(gè)text.csv
的文件,文件內(nèi)容為:
,,model,num
A,1,CPU,80
A,2,GPU,152
A,4,FLASH,113
B,3,SSD,354
B,5,HDD,1
C,1,USB,231
C,5,TYPE-C,35
C,8,MIC-USB,12
C,1,DRIVE,7
6.1.2 讀取文本文件函數(shù)read_csv()
函數(shù)語法:
詳細(xì)參數(shù)請查看官方文檔:Pandas.read_csv()
Pandas.read_csv(filepath_or_buffer,sep=',',delimiter=None,header='infer',names=None,index_col=None,usecols=None,prefix=None,……)
-
sep
:指定使用的分隔符,默認(rèn)用","分隔 -
header
:指定行數(shù)用來作為列名 -
names
:用于結(jié)果的列名列表,如果文件不包含標(biāo)題行,則應(yīng)該將參數(shù)設(shè)置為None
讀取Text文件函數(shù)
read_table()
與read_csv()
相似,只不過read_table()
函數(shù)默認(rèn)使用"\t"為分隔符。
代碼:
讀取上文中生成的test.csv
文件
import pandas as pd
data = pd.read_csv('./test.csv')
print(data)
輸出:
Unnamed: 0 Unnamed: 1 model num
0 A 1 CPU 80
1 A 2 GPU 152
2 A 4 FLASH 113
3 B 3 SSD 354
4 B 5 HDD 1
5 C 1 USB 231
6 C 5 TYPE-C 35
7 C 8 MIC-USB 12
8 C 1 DRIVE 7
可以通過del data['Unnamed: 0']
來刪除該列。
6.2 讀寫EXCLE
文件
Excle文件是常見的存儲數(shù)據(jù)文件,它里面均是以二維表格的形式顯示的,可以對數(shù)據(jù)進(jìn)行統(tǒng)計(jì)分析等操作,常見擴(kuò)展名為.xls
和.xlsx
兩種格式,對于Excle文件的讀寫常用的兩個(gè)方法為to_excle()
和read_excle()
兩種方法。
6.2.2 寫入Excle文件to_excle()
方法
函數(shù)語法:
詳細(xì)參數(shù)請查看官方文檔:DataFrame.to_excel()
DataFrame.to_excel(excle_writer,sheet_name='Sheet1',na_rep='',float_format=None,columns=None,header=True,index=True,……)
-
excle_writer
:表示讀取的文件路徑 -
sheet_name
:表示工作表名稱,默認(rèn)為Sheet1
-
na_rep
:表示缺失數(shù)據(jù) -
index
:表示是否寫行索引,默認(rèn)為True
代碼:
讀取上文中生成的test.csv
文件
import pandas as pd
data_excle = pd.DataFrame(
{
"model": [
'CPU', 'GPU', 'FLASH', 'SSD', 'HDD', 'USB', 'TYPE-C', 'MIC-USB',
'DRIVE'
],
"num": [80, 152, 113, 354, 1, 231, 35, 12, 7]
},
index=[['A', 'A', 'A', 'B', 'B', 'C', 'C', 'C', 'C'],
[1, 2, 4, 3, 5, 1, 5, 8, 1]])
data_excle.to_excel('./test.xlsx', 'TestExcle')
輸出:
將在根目錄輸出文件名為test.xlsx
的表格,表格內(nèi)容如圖。
6.2.2 讀取Excle文件read_excle()
方法
函數(shù)語法:
詳細(xì)參數(shù)請查看官方文檔:Pandas.read_excel()
Pandas.read_excle(io,sheet_name=0,header=0,name=None,index_col=None,**kwds)
-
io
:表示路徑對象 -
sheet_name
:指定要讀取的工作表,默認(rèn)為0 -
header
:用于解析DataFrame的列標(biāo)簽 -
names
要使用的列名稱
代碼:
讀取上文中生成的test.xlsx
文件,由于Excle中合并的單元格會產(chǎn)生缺失值,使用ffill()
方法進(jìn)行向下填充。
import pandas as pd
data = pd.read_excel('./test.xlsx').ffill()
print(data)
輸出:
Unnamed: 0 Unnamed: 1 model num
0 A 1 CPU 80
1 A 2 GPU 152
2 A 4 FLASH 113
3 B 3 SSD 354
4 B 5 HDD 1
5 C 1 USB 231
6 C 5 TYPE-C 35
7 C 8 MIC-USB 12
8 C 1 DRIVE 7
6.3 讀寫HTML
文件
6.3.1 讀取HTML表格方法read_html()
方法
函數(shù)語法:
詳細(xì)參數(shù)請查看官方文檔:pandas.read_html()
Pandas.read_html(io,match='.+',flavor=None,header=None,index_col=None,skiprows=None,attrs=None)
-
io
:表示路徑對象 -
header
:表示指定列標(biāo)題所在的行 -
index_col
:表示指定行標(biāo)題對應(yīng)的列 -
attrs
:默認(rèn)為None,用于表示表格的屬性值
代碼:
將使用read_html()
方法讀取http://gaokao.xdf.cn/201805/10781393.html的表格:
import requests
import pandas as pd
html_data = requests.get('http://gaokao.xdf.cn/201805/10781393.html')
html_read = pd.read_html(html_data.content, encoding='utf-8')
print(html_read[0])
輸出:
0 1 2 3
0 排名 學(xué)校名稱 省市 總分
1 1 清華大學(xué) 北京 95.3
2 2 北京大學(xué) 北京 78.6
3 3 浙江大學(xué) 浙江 73.9
4 4 上海交通大學(xué) 上海 73.1
.. .. ... .. ...
95 94 中國政法大學(xué) 北京 37.6
96 96 大連醫(yī)科大學(xué) 遼寧 37.5
97 97 中國石油大學(xué)(北京) 北京 37.3
98 98 西北大學(xué) 陜西 37.2
99 98 中國傳媒大學(xué) 北京 37.2
[100 rows x 4 columns]
6.3.2 寫入HTML表格方法to_html()
方法
函數(shù)語法:
詳細(xì)參數(shù)請查看官方文檔:DataFrame.to_html()
DataFrame.to_html(buf,index,header)
-
buf
:輸出路徑 -
index
:行索引,默認(rèn)為True
-
header
:列索引,默認(rèn)為True
代碼:
將上文讀取到的表格的前十名寫入到test.html
中,不保留行列索引:
html_read[0][:11].to_html('./test.html', index=False, header=False)
輸出:
6.4 讀寫sql
文件
Padnas支持Mysql、Oracle、SQLite等主流數(shù)據(jù)庫的讀寫操作,為了高效讀取數(shù)據(jù)庫中的數(shù)據(jù),需要引入SQLAlchemy軟件,引入之后Pandas的io.sql
模塊將讀寫數(shù)據(jù)庫,其中提供的常用函數(shù)如下表所示:
函數(shù)名稱 | 說明 |
---|---|
read_sql_table() |
將讀取的整張數(shù)據(jù)表中的數(shù)據(jù)轉(zhuǎn)化成DataFrame對象 |
read_sql_query() |
將sql語句讀取的結(jié)果轉(zhuǎn)換成DataFrame對象 |
read_sql() |
上述兩個(gè)函數(shù)的結(jié)合,既可以讀數(shù)據(jù)表也可讀SQL語句 |
to_sql() |
將數(shù)據(jù)寫入到SQL數(shù)據(jù)庫中 |
本文將使用mysql數(shù)據(jù)庫,Python需要使用:
pip install mysql-connector-python
如果使用的是Conda則需要使用:
conda install mysql-connector-python
安裝模塊。
6.4.1 寫入數(shù)據(jù)庫函數(shù)to_sql()
函數(shù)語法:
詳細(xì)參數(shù)請查看官方文檔:DataFrame.to_sql() Series.to_sql()
to_sql(name,con,schema=None,if_exists='fail',index=True,index_label=None,chunksize=None,dtype=None)
-
name
:表示數(shù)據(jù)庫表的名稱 -
con
:接收數(shù)據(jù)庫連接信息 -
if_exists
:可以取值為fail
,replace
,append
等,默認(rèn)為fail
在對數(shù)據(jù)庫進(jìn)行寫入前需要首先創(chuàng)建數(shù)據(jù)庫,使用mysql終端輸入:
create database test;
創(chuàng)建test數(shù)據(jù)庫。更多數(shù)據(jù)庫指令參照:Sql教程 MySQL 教程
代碼:
創(chuàng)建一個(gè)DataFrame
對象并將其寫入test
數(shù)據(jù)庫中的students
表。
from sqlalchemy import create_engine
import pandas as pd
df = pd.DataFrame({
"班級": ["一年級", "二年級", "三年級", "四年級"],
"男生人數(shù)": [25, 23, 27, 30],
"女生人數(shù)": [19, 17, 20, 20]
})
engine = create_engine("mysql+mysqlconnector://root:root@127.0.0.1:3306/test")
df.to_sql('students',engine)
輸出:
通過在Mysql數(shù)據(jù)庫中輸入:
use test; /*使用test數(shù)據(jù)庫*/
show tables; /*顯示數(shù)據(jù)庫中的數(shù)據(jù)表*/
select *from students; /*輸出students數(shù)據(jù)表*/
至此,表格已經(jīng)創(chuàng)建成功了。
6.4.1 讀取數(shù)據(jù)表函數(shù)read_sql()
函數(shù)語法:
詳細(xì)參數(shù)請查看官方文檔:pandas.read_sql()
pandas.read_sql(sql,con,index_col=None,coerce_float=True,params=None,parse_dates=None,columns=None,chunksize=None)
-
sql
:表示被執(zhí)行的SQL語句 -
con
:接收數(shù)據(jù)庫連接,表示數(shù)據(jù)庫的連接信息 -
columns
:從SQL表中選擇列名列表
注意:通過
create_engine()
函數(shù)創(chuàng)建連接時(shí),需要指定格式如下:'數(shù)據(jù)庫類型+數(shù)據(jù)庫驅(qū)動名稱//用戶名:密碼@機(jī)器地址:端口號/數(shù)據(jù)庫名'
代碼:
讀取上文中test/students
數(shù)據(jù)表中的內(nèi)容并寫入名稱為data_sql
的DataFrame
對象中。
from sqlalchemy import create_engine
import pandas as pd
engine = create_engine(
"mysql+mysqlconnector://root:root@127.0.0.1:3306/test")
sql = "select *from students"
data_sql = pd.read_sql(sql, engine)
print(data_sql)
輸出:
index 班級 男生人數(shù) 女生人數(shù)
0 0 一年級 25 19
1 1 二年級 23 17
2 2 三年級 27 20
3 3 四年級 30 20