首先,調用read_excel()
方法讀取數據
import pandas as pd
df = pd.read_excel("data.xlsx")
df
姓名 班級 語文 數學
0 張三 一班 99 90
1 李四 一班 78 NaN
2 王五 一班 70 88
3 小明 二班 88 99
4 小紅 二班 98 77
導入數據後,首先要熟悉數據。
shape屬性:可以幫助我們查看數據包含幾行幾列
df.shape
(5,4)
從結果可以看出,這份數據一共有5行4列
**head()或tail()**方法:head()方法可以幫助我們查看數據的前幾行,tail()方法可以幫助我們查看數據的後幾行
df.head()
姓名 班級 語文 數學
0 張三 一班 99 90
1 李四 一班 78 NaN
2 王五 一班 70 88
3 小明 二班 88 99
4 小紅 二班 98 77
df.tail(2)
姓名 班級 語文 數學
3 小明 二班 88 99
4 小紅 二班 98 77
head()方法默認展示的是前5行數據,tail()方法默認展示的是後5行數據。當他們傳入指定數字時,就可以幫我們獲取指定的行數。
dtypes
屬性:可以幫助我們查看每列數據的數據類型
df.dtypes
姓名 object
班級 object
語文 int64
數學 int64
dtype object
object
類型是字符串,int64
是整型,float64
是浮點型
**describe()**方法:可以幫助我們查看數值型變量的描述性統計量
df.describe()
語文 數學
count
mean
std
min
25%
50%
75%
max
count
表示計數,mean
表示平均值,std
表示標准差,min
和max
分別表示最小值和最大值,25%
、50%
、75%
表示四分位數
**info()**方法:可以幫助我們查看數據的列名、數據類型、非空值、以及內存占用情況
df.info()
<class "pandas.core.frame.DataFrame">
RangeIndex: 6 entries, 0 to 5
Data columns (total 5 columns):
# Column Non-Null Count Dtype
-- ----- ------- ----- -----
0 姓名 6 non-null object
1 班級 6 non-null object
2 語文 6 non-null int64
3 數學 5 non-null int64
dtypes: int64(2),object(2)
memory usage: 368.0+ bytes
可以清楚的看到每一個列字段的列名、非空值和數據類型。另外“數學”這一列只有5個非空值,表明該列存在缺失值。同時memory usage
為我們展示了這份數據占用內存的大小
通過數據預覽,可以做到對數據心中有數。然而,在正式進行數據處理之前,我們必須進行數據預處理,它直接關系到分析結果的准確性。
有些數據會存在缺失值(NaN
)、重復值
檢測缺失值
其實檢測缺失值最簡單的方法就是調用**info()
**方法,通過觀察每一列的非空值,即可判斷出哪些列存在缺失值
另外還有一種檢測是否存在缺失值的方法,即**isnull()
方法搭配any()
**方法,具體介紹如下
isnull()
:對於缺失值,返回True;對於非缺失值,返回False
any()
:一個序列中有一個True,則返回True,否則返回False
df.isnull() ###打印出每個數據的True或False值
姓名 班級 語文 數學 英語
0 False False False False False
1 False False False True False
2 False False False False False
3 False False False False False
4 False False False False False
5 False False False False False
df.isnull().any(axis=1) ###axis=1,可以幫助我們打印出每一行是否存在缺失值
0 False
1 True
2 False
3 False
4 False
5 False
df.isnull().any() ###不指定打印的是每一列 是否存在缺失值
姓名 False
班級 False
語文 False
數學 True
英語 False
檢測重復值
調用**duplicated()**方法,可以用於檢測重復值
df.duplicated()
0 False
1 False
2 True
3 False
4 False
5 False
df.duplicated().any()
True
調用duplicated()方法,可以返回某一行是否是重復值。由於第4行和第3行的數據屬於重復行,因此返回True。接著使用any()方法,即可判斷出數據中存在重復值
缺失值處理
通常使用NaN
表示缺失值。如果存在缺失值,我們可以調用**fillna()
方法來填充數據。也可以用dropna()
**方法刪除缺失值
df = df.fillna(0) ###將NaN修改為0
df = df.dropna() ###將有缺失值的一行刪除
重復值處理
**drop_duplicates()**方法,它可以對所有值進行重復值判斷,並默認保留第一個(行)值
df
姓名 年齡
0 張三 19
1 張三 19
2 李四 20
df = df.drop_duplicates()
姓名 年齡
0 張三 19
2 李四 20
可以幫我們刪除重復行,只保留第一行的數據
數據替換
調用**replace()**方法,可以實現數據替換,例如replace(A,B)
,表示直接將A替換成B
df['數學'] = df['數學'].replace(0,90)
按行/列篩選,loc
和iloc
兩種方法,用於行/列篩選
loc
:利用標簽索引的方式獲取行或列
iloc
:利用位置索引的方式獲取行或列
選取一列
df['f']
df.loc[:,'f']
df.iloc[:,[1]]
選取多列
df[['e','f']]
df.loc[:,['e','f']]
df.iloc[:,[0,1]]
選取一行
df.loc['b',:]
df.iloc[1,:]
選取多行
df.loc[['a','b'],:]
df.iloc[[0,1],:]
同時選取行列
df.loc['b','f']
df.iloc[1,1]
同時選取多行多列
df.loc[['a','b'],['f','g']]
df.iloc[[0,1],[1,2]]
df = df.set_index("姓名")
df
班級 語文 數學 英語
姓名
趙一 一班 98 96.0 97
王二 一班 88 90.0 75
張三 一班 86 87.0 93
李四 二班 93 92.0 81
朱五 二班 95 99.0 60
df.loc[['趙一','李四']]
班級 語文 數學 英語
姓名
趙一 一班 98 96.0 97
李四 二班 93 92.0 81
df.iloc[[0,3]]
班級 語文 數學 英語
姓名
趙一 一班 98 96.0 97
李四 二班 93 92.0 81
調用set_index()方法,我們將數據框中的“姓名“列設置為新的索引。我們既可以用loc
傳入標簽索引的方式,獲取這兩位同學的數據信息,也可以用iloc
傳入位置索引的方式獲取信息
按條件篩選,有時候我們想要篩選出符合某些條件的數據,提供了**query()
、isin()
、between()
**
篩選數學成績在95分以上的同學
df[df['數學']>95]
篩選語文和數學成績都在90分以上的同學
df.query("語文>90 & 數學>90")
篩選語文成績是88或95的同學
df[df['語文'].isin(['88','95'])]
篩選數學成績在85到95之間的同學
df[df['數學'].between(85,95)] ###不包含邊界值85和95
argmax()
求最大值的索引值mode()求眾數idxmax()
求最大值的索引值var()求方差argmin()
求最小值的索引值std()求標准差idxmin()
求最小值的索引值median()求中位數unique()去重(唯一值)計算每個人的總成績
df['總分'] = df['語文'] + df['數學'] + df['英語']
df
姓名 班級 語文 數學 英語 總分
0 趙一 一班 98 96.0 97 291.0
1 王二 一班 88 90.0 75 253.0
2 張三 一班 86 87.0 93 266.0
3 李四 二班 93 92.0 81 266.0
4 朱五 二班 95 99.0 60 254.0
如果想計算出每個班級的總人數,應該怎麼做
df['班級'].value_counts()
一班 3
二班 2
Name: 班級, dtype:int64
計算出每個人的平均分,並保留兩位小數
df['平均分']=df['總分'].apply(lambda x: round(x/3,2))
df
姓名 班級 語文 數學 英語 總分 平均分
0 趙一 一班 98 96.0 97 291.0 97.00
1 王二 一班 88 90.0 75 253.0 84.33
2 張三 一班 86 87.0 93 266.0 88.67
3 李四 二班 93 92.0 81 266.0 88.67
4 朱五 二班 95 99.0 60 254.0 84.67
apply()將”總分“這一列的每個元素,都除以3且結果保留兩位小數。
相當於
a=[1,2,3,4,5]
c=list(map(lambda x:x-1,a))
print(c)
[0, 1, 2, 3, 4]
數據排序與排名
數據排序:sort_value()方法可以實現
DataFrame.sort_value(by,ascending,inplace)
by:列名(字符/字符列表)
ascending:是否升序排序,默認為升序:True
inplace:是否修改原DataFrame
按照總分降序排序
df.sort_values(by = ["總分"],ascending=False,inplace=True)
df
姓名 班級 語文 數學 英語 總分 平均分
0 趙一 一班 98 96.0 97 291.0 97.00
2 張三 一班 86 87.0 93 266.0 88.67
3 李四 二班 93 92.0 81 266.0 88.67
4 朱五 二班 95 99.0 60 254.0 84.67
1 王二 一班 88 90.0 75 253.0 84.33
###如果總分相同,再按英語來排序
df.sort_values(by = ["總分","英語"],ascending=[False,True],inplace=True)
df
姓名 班級 語文 數學 英語 總分 平均分
0 趙一 一班 98 96.0 97 291.0 97.00
3 李四 二班 93 92.0 81 266.0 88.67
2 張三 一班 86 87.0 93 266.0 88.67
4 朱五 二班 95 99.0 60 254.0 84.67
1 王二 一班 88 90.0 75 253.0 84.33
數據排名
當我們對數據完成排序後,就可以進行數據排名了。調用rank()方法可以實現。
DataFrame.rank(method,ascending)
method:排序方式
ascending:是否升序排序,默認為True
method有5個常用選項
first
average
min
max
dense
按照總分來排名
df['排名'] = df['總分'].rank(method='dense',ascending=False).astype('int')
df
姓名 班級 語文 數學 英語 總分 平均分 排名
0 趙一 一班 98 96.0 97 291.0 97.00 1
2 張三 一班 86 87.0 93 266.0 88.67 2
3 李四 二班 93 92.0 81 266.0 88.67 2
4 朱五 二班 95 99.0 60 254.0 84.67 3
1 王二 一班 88 90.0 75 253.0 84.33 4
由於這裡返回的排名值是一個浮點型,因此需要調用astype()
方法實現數據類型轉換
數據合並與連接:用於實現對多表的操作
數據合並:將同種性質表的不同部分合並在一起,一般不需要考慮公共列
分為橫向合並和縱向合並兩種方式。使用concat()
方法
df
a b c
0 10 20 30
1 40 50 60
2 70 80 90
df2
d
0 35
1 65
2 95
###橫向合並
df_concat=pd.concat([df,df2],axis=1)
df_concat
a b c d
0 10 20 30 35
1 40 50 60 65
2 70 80 90 95
df3
a b c
0 110 120 130
###縱向合並,使用reset_index()可以幫助我們重置合並後的索引。不然就是 0 1 2 0
df_concat=pd.concat([df,df3],axis=0).reset_index(drop=True)
df_concat
a b c
0 10 20 30
1 40 50 60
2 70 80 90
3 110 120 130
如果想要加入學生信息表的數據
df3 = pd.read_excel("學生信息表.xlsx")
df3
姓名 性別 住址
0 王二 男 朝陽
1 李四 女 朝陽
2 朱五 男 海澱
3 黃七 男 海澱
4 趙一 女 朝陽
5 馬六 女 海澱
6 張三 男 海澱
pd.concat([df_concat,df3],axis=1)
姓名 班級 語文 數學 英語 姓名 性別 住址
0 趙一 一班 98 96.0 97 王二 男 朝陽
1 王二 一班 88 90.0 75 李四 女 朝陽
2 張三 一班 86 87.0 93 朱五 男 海澱
3 李四 二班 93 92.0 81 黃七 男 海澱
4 朱五 二班 95 99.0 60 趙一 女 朝陽
5 馬六 三班 86 90 89 馬六 女 海澱
6 黃七 三班 96 88 91 張三 男 海澱
由於concat()方法合並數據依賴索引,當兩表的數據順序不一致時,就會產生這類錯誤,姓名對不上。
要想規避,以姓名為連接鍵
數據連接:將不同性質表連接在一起,一般需要考慮公共列
調用merge()方法實現數據連接
pd.merge(left,right,how,on)
left:左側DataFrame對象
right:右側DataFrame對象
how:數據合並的方式
on:連接鍵
兩個數據框DataFrame
想要進行數據連接,需要依賴某個“公共列”作為連接鍵,數據連接後的結果受參數how
的影響
NaN
補充(左連接)NaN
補充(右連接)df
a b c
0 10 20 30
1 40 50 60
2 70 80 90
df2
a d
0 10 35
1 40 65
2 75 95
pd.merge(df,df2,how='left',on='a')
a b c d
0 10 20 30 35
1 40 50 60 65
2 70 80 90 NaN
pd.merge(df,df2,how='right',on='a')
a b c d
0 10 20 30 35
1 40 50 60 65
2 75 NaN NaN 95
pd.merge(df,df2,how='inner',on='a')
a b c d
0 10 20 30 35
1 40 50 60 65
pd.merge(df,df2,how='outer',on='a')
a b c d
0 10 20 30 35
1 40 50 60 65
2 70 80 90 NaN
3 75 NaN NaN 95
數據分組與透視表
通過合並和連接得到的大表,一般用於“數據分組”和“數據透視表”的計算
DataFrame.groupby(by).聚合函數
by:分組依據
一般分組和聚合是搭配使用的,分組後調用聚合函數完成聚合操作
以班級分組,計算每個班級的學生數量
df_merge = pd.merge(df_concat,df3,how='inner',on='姓名')
df_merge
姓名 班級 語文 數學 英語 性別 住址
0 趙一 一班 98 96.0 97 男 朝陽
1 王二 一班 88 90.0 75 女 朝陽
2 張三 一班 86 87.0 93 男 海澱
3 李四 二班 93 92.0 81 男 海澱
4 朱五 二班 95 99.0 60 女 朝陽
5 馬六 三班 86 90 89 女 海澱
6 黃七 三班 96 88 91 男 海澱
df_merge.groupby("班級").count()
姓名 語文 數學 英語 性別 住址
班級
一班 3 3 3 3 3 3
二班 2 2 2 2 2 2
三班 2 2 2 2 2 2
df_merge.groupby("班級")['姓名'].count()
班級
一班 3
二班 2
三班 2
Name:姓名,dtype:int64
調用groupby()
方法並搭配聚合函數count()
,按照班級這列進行分組並對其他列進行計數,統計出每個班級的學生數量,實際上只需要對姓名這列計數就夠了。
以班級、住址分組
df_merge.groupby(['班級','住址'])['姓名'].count()
班級 住址
一班 朝陽 2
海澱 1
二班 朝陽 1
海澱 1
三班 海澱 2
Name:姓名,dtype:int64
以班級分組,計算每個班語文成績最高的分數
df_merge.group("班級")['語文'].max()
班級
一班 98
二班 96
三班 95
Name:語文,dtype:int64
數據透視表:pivot_table()可以實現數據透視表
data
相當於Excel中的“選中數據源”index
相當於數據透視表字段中的行columns
相當於數據透視表字段中的列values
相當於數據透視表字段中的值aggfunc
相當於計算類型margins
相當於結果中的總計margins_name
相當於修改總計名fill_value
將缺失值用某個指定值填充以住址為行,班級為列,計算每個班級的學生數量,並統計他們的合計值
pd.pivot_table(
df_merge,values="姓名",
columns="班級",index="住址",
aggfunc="count",fill_value=0,
margins_name='合計',margins=True
)
班級 一班 二班 三班 合計
住址
朝陽 2 1 0 3
海澱 1 1 2 4
合計 3 2 2 7
Excel拆分與合並
按條件將Excel文件拆分到不同的工作簿
import pandas as pd
df = pd.read_excel("三年級總成績單.xlsx")
for i in df['班級'].unique():
df[df['班級']==i].to_excel(f"{i}.xlsx",index=False)
按條件將Excel拆分到不同的工作表
import pandas as pd
df = pd.read_excel("三年級總成績單.xlsx")
for i in df['班級'].unique():
df[df['班級']==i].to_excel(
"三年級總成績單.xlsx",index=False,sheet_name=f"{i}"
)
但是執行後發現每次生成的工作表都會覆蓋前一個,最終只剩下一個表,用這個方法實現
import pandas as pd
df = pd.read_excel('三年級總成績單.xlsx')
writer = pd.ExcekWriter("三年級總成績單.xlsx")
df.to_excel(writer,sheet_name='總成績',index=False)
for j in df['班級'].unique():
df[df['班級']==j].to_excel(writer,sheet_name=j,index=False)
ExcelWriter()
方法,他會幫助我們建立一個空的容器對象writer
批量將不同的工作表合並到一個excel文件
import pandas as pd
sheet_names = pd.ExcelFile("三年級分班成績單.xlsx").sheet_names
df_all = pd.DataFrame()
for i in sheet_names:
df = pd.read_excel("三年級分班成績單.xlsx",sheet_name=i)
df_all = df_all.append(df)
df_all.to_excel(
'三年級分班成績單.xlsx',sheet_name='總成績'
)
ExcelFile()
會得到一個ExcelFile
對象。該對象有一個很好用的sheet_names屬性,它能夠獲取當前表格中所有工作表的名稱,並以一個列表返回