文本檔案的讀取
Pandas讀取官方檔案查閱地址 Input/Output — pandas 0.24.2 documentation (pydata.org)
read_csv\read_table(filepath_or_buffer,sep=’\t’,header=’infer’,names=None,index_col=None,usecols=None,dtype=None,converters=None,skiprows=None,skipfooter=None,nrows=None,na_values=None,skip_blank_lines=True,parse_dates=False,thousands=None,comment=None,encoding=None)
讀取txt,注意到以下問題:如何忽略其他不相關內容,手動添加#;如何添加變數名稱;如何避免編號中’00’的消失,

import pandas as pd
data1=pd.read_table(filepath_or_buffer=r'D:\Projects\Python\Doing\pythonProject\data\data1.txt',
sep=',',# 指定分隔符
header=None, # 不需要將原始資料中的第一行讀作表頭
names=['id','name','gender','occupation'], # 為各列起變數名稱
skiprows=2, #跳過起始的兩行資料
skipfooter=2, #跳過末尾的兩行資料
comment='#', # 不讀取'#'開頭的資料行
converters={'id':str}, #對工號變數進行型別轉換,避免開頭的00消失
encoding='gbk'
)
print(data1)
'''
id name gender occupation
0 00446 張敏 女 前端工程師
1 00483 李琴 女 Java開發工程師
2 00552 趙東來 男 資料分析師
3 00589 丁順昌 男 資料分析師
'''
電子表格的讀取
read_excel(io,sheetname=0,header=0,skiprows=Nne,skip_footer=0,index_col=None,names=None,parse_cols=None,parse_dates=False,na_values=None,thousands=None,convert_float=True)

import pandas as pd
data2=pd.read_excel(io=r'D:\Projects\Python\Doing\pythonProject\data\data2.xlsx',
header=None, # 不需要將原始資料中的第一行讀作表頭
names=['id','date','prod_name','color','price'], # 為各列起變數名稱
converters={'0':str}, #字典中的鍵必須為0,因為原始表中沒有列名稱
na_values='未知' # 原資料表中“未知”轉換為缺失值
)
print(data2)
'''
id date prod_name color price
0 23146 2016-03-18 連衣裙 237 白色
1 1344527 2017-06-12 牛仔褲 368 藍色
2 223685 2018-02-10 皮鞋 589 NaN
3 37249 2017-07-17 寸衫 299 白色
4 368241 2016-03-23 板鞋 299 藍色
5 1127882 2018-09-17 西裝 1599 黑色
'''
資料庫資料的讀取
讀入SQL Server需要使用pymssql模塊,在jupyter中輸入“!pip install pymssql”;
讀入MySQL需要使用Pymysql模塊,在jupyter中輸入“!pip install pymysql”,
然后基于兩個模塊各自的connect函式構建資料庫與python之間的橋梁,最后在搭建好連接的基礎上使用pandas模塊中的read_sqll函式實作資料庫資料的讀取,
1.connect函式
(1)pymssql.connect(server=None,user=None,password=None,database=Nonesharset=None)

(2)pymysql.connect(host=None,user=None,password=’’,database=None,port=0,charset=’’)

2.read函式
pd.read_sql(sql,con,index_col=None,coerce_float=True,parse_dates=None,columns=None)

SQL SERVER連接
import pymssql
import pandas as pd
# 連接SQL Server資料庫
connect=pymssql.connect(server='localhost',# 指定服務器名稱
user='', # 指定訪問資料庫的用戶名
password='', # 指定訪問資料庫的密碼
database='train', # 指定資料所在資料庫的名稱
charset='utf8' # 指定UTF-8字符集,避免中文亂碼
)
# 讀取資料
data=pd.read_sql("select * from sec_buildings where direction='朝南'",con=connect)
# 關閉連接
connect.close()
# 資料輸出
data.head()
MySQL連接
import pymysql
import pandas as pd
# 連接MySQL資料庫
connect=pymysql.connect(host='localhost',# 指定服務器名稱
user='root', # 指定訪問資料庫的用戶名
password='123456', # 指定訪問資料庫的密碼
database='wx', # 指定資料所在資料庫的名稱
port=3306, # 指定資料庫連接的埠號
charset='utf8' # 指定UTF-8字符集,避免中文亂碼
)
# 讀取資料
data=pd.read_sql("select * from wx_gift",connect)
# 關閉連接
connect.close()
# 資料輸出
print(data)
'''
gift_id name point_needed num_released img
0 1 黨員學習筆記 100 3 /static/photo/禮品1.jpg
1 2 古典書簽 50 23 /static/photo/禮品2.jpg
2 3 古風扇書簽 300 4 /static/photo/禮品5.jpg
3 4 黨建紀念品 1000 10 /static/photo/禮品4.jpg
'''
import pandas as pd
# 讀取資料
data3=pd.read_excel(io=r'D:\Projects\Python\Doing\pythonProject\data\data3.xlsx')
# 查看資料規模
print(data3.shape
# (3000, 6)
# 查看表中各變數的資料型別
print(data3.dtypes)
'''
id int64
gender object
age float64
edu object
custom_amt object
order_date object
dtype: object
'''
資料的概覽與清洗
從外部環境將資料讀入到Python中后,首先要了解資料,資料規模、各變數的資料型別、是否存在重復值、缺失值等,
1.資料型別的判斷和轉換,讀取資料,了解資料規模、各變數的資料型別
- astype用于資料型別的強制轉換,常用轉換型別包括str、float、int,
- 由于消費金額custom_amt變數中帶有‘¥’,所以資料型別轉換之前必須將包其洗掉(通過字串切片方法洗掉,[1:]表示從字符的第二個元素開始截斷),
- 對于字符轉日期問題,推薦使用更加靈活的pandas的to_datetime方法,在format引數的調解下,可以識別任意格式的字符型日期值,
import pymysql
import pandas as pd
# 讀取資料
data3=pd.read_excel(io=r'D:\Projects\Python\Doing\pythonProject\data\data3.xlsx')
# 查看資料規模
# print(data3.shape
# (3000, 6)3000行6列
# 查看表中各變數的資料型別
# print(data3.dtypes)
'''
id int64
gender object
age float64
edu object
custom_amt object
order_date object
dtype: object
'''
# 數值型轉字符型
data3['id']=data3['id'].astype(str)
# 字符型轉數值型
data3['custom_amt']=data3['custom_amt'].str[1:].astype(float)
# 字符型轉日期型
data3['order_date']=pd.to_datetime(data3['order_date'],format='%Y年%m月%d日')
# 重新查看資料集的各變數型別
# print(data3.dtypes)
'''
id object
gender object
age float64
edu object
custom_amt float64
order_date datetime64[ns]
dtype: object
'''
# 預覽資料的前五行
print(data3.head())
'''
id gender age edu custom_amt order_date
0 890 female 43.0 NaN 2177.94 2018-12-25
1 2391 male 52.0 NaN 2442.18 2017-05-24
2 2785 male 39.0 NaN 849.79 2018-05-15
3 1361 female 26.0 NaN 2482.22 2018-05-16
4 888 female 61.0 本科 2027.90 2018-01-21
'''
2.冗余資料的判斷和處理,監控資料表中是否存在“臟”資料,如冗余的重復觀測值和缺失值等
可以通過duplicated方法進行“臟”資料的識別和處理,沒有重復值回傳False,若發現了重復值,可使用drop_duplicates方法將冗余資訊洗掉,
在duplicated方法對資料行作重復性判斷時,會回傳一個與原資料行數相同的序列,如果資料行沒有重復則對應False,否則對應True,為了得到最終的判斷結果,需要再用any方法,即序列中只要存在一個true則回傳true,
# 判斷是否存在重復觀測值
print(data3.duplicated().any())
# False
3.缺失資料的判斷預處理,通常從兩個方面入手:
①變數的角度,即判斷每個變數中是否包含缺失值;
②資料行的角度,即判斷每行資料中是否包含缺失值,
關于缺失值NaN的判斷可以使用isnull方法,它會回傳與原資料行列數相同的矩陣,并且矩陣的元素為bool型別的值,
為了得到每一列的判斷結果,仍然需要使用any方法且設定axis引數為0;
統計各變數的缺失值個數可以在isnull的基礎上使用sum方法,同樣需要設定axis引數為0;
計算缺失比例就是在缺失數量的基礎上除以總的樣本量(shape方法回傳資料集的行數和列數,[0]表示取出對應的資料行數),
說明:axis=0行數增多,axis=1列數增多
對于缺失值的處理,最常用的方法無外乎洗掉法、替換法和插補法,
- 洗掉法指將缺失值所在的觀測行洗掉,前提缺失行比例非常低如在5%以內;或者洗掉缺失值所對應的變數,前提是改變數中包含的缺失值比例非常高如70%左右,
- 替換法是指直接利用缺失變數的均值、中位數或眾數替換該變數中的缺失值,其好處是處理速度快,弊端是容易產生有偏估計,導致缺失值替換的準確性下降,
- 插補法是指利用有監督的機器學習方法(如回歸模型、樹模型、網路模型等)對缺失值做預測,其優勢在于預測的準確性高,缺點是需要大量的計算,導致缺失值的處理速度大打折扣,
# 判斷各變數中是否存在缺失值
print(data3.isnull().any(axis=0))
'''
id False
gender True
age True
edu True
custom_amt False
order_date False
dtype: bool
'''
# 各變數中缺失值的數量
print(data3.isnull().sum(axis=0))
'''
id 0
gender 136
age 100
edu 1927
custom_amt 0
order_date 0
dtype: int64
'''
# 各變數中缺失值的比例
print(data3.isnull().sum(axis=0)/data3.shape[0])
'''
id 0.000000
gender 0.045333
age 0.033333
edu 0.642333
custom_amt 0.000000
order_date 0.000000
dtype: float64
'''
# 判斷各資料行中是否存在缺失值
print(data3.isnull().any(axis=1))
'''
0 True
1 True
2 True
3 True
4 False
...
2995 True
2996 False
2997 True
2998 False
2999 True
Length: 3000, dtype: bool
'''
# 缺失觀測值的行數
print(data3.isnull().any(axis=1).sum())
# 2024
# 缺失觀測值的比例
print(data3.isnull().any(axis=1).sum()/data3.shape[0])
# 0.6746666666666666
# 洗掉變數,如洗掉缺失率非常高的edu變數
data3.drop(labels='edu',axis=1,inplace=True)
print(data3.head())
'''
id gender age custom_amt order_date
0 890 female 43.0 2177.94 2018-12-25
1 2391 male 52.0 2442.18 2017-05-24
2 2785 male 39.0 849.79 2018-05-15
3 1361 female 26.0 2482.22 2018-05-16
4 888 female 61.0 2027.90 2018-01-21
'''
# 洗掉觀測值,如洗掉age變數中所對應的缺失觀測值
data3_new=data3.drop(labels=data3.index[data3['age'].isnull()],axis=0)
print(data3_new.shape)
# (2900, 5)
# 替換法處理缺失觀測值
data3.fillna(value={'gender':data3['gender'].mode()[0],# 使用性別的眾數替換缺失性別
'age':data3['age'].mean() # 使用年齡的平均值替換缺失年齡
},
inplace=True # 原地修改資料
)
print(data3.isnull().sum(axis=0))
'''
id 0
gender 0
age 0
custom_amt 0
order_date 0
dtype: int64
'''
資料的參考
在pandas模塊中,可以使用iloc、loc或ix方法既可以篩選也可以對變數進行挑選,他們的語法相同,可以表示成[rows_select,cols_select],
- iloc只能通過行號和列號進行資料的篩選,可以將iloc中的’i’理解為integer,即只能向[rows_select,cols_select]指定整數串列,對于這種方式的索引,第一行貨第一列必須用0表示,既可以向rows_select或cols_select指定連續的整數編號(即切片用法start🔚step,end的值取不到),也可以指定簡短的整數編號,
- loc可以將’l’理解為label,即可以向[rows_select,cols_select]指定具體的行標簽(行名稱)和列標簽(變數名),注意,這里是標簽而不再是整數索引,除此之外loc方法還可以將索引中的rows_select指定為資料的篩選條件,但在iloc中是不允許這樣使用的,
- ix是iloc和loc的混胡,可以將ix理解為mix,
import pandas as pd
# 構造資料框
df1=pd.DataFrame({'name':['甲','乙','丙','丁','戊'],
'gender':['男','女','女','女','男'],
'age':[23,26,22,25,27],
'edu':['本科','本科','碩士''本科','碩士']
},
columns=['name','gender','edu','age']
)
# 查看資料預覽
# print(df1)
# 取出資料集的中間三行(即所有女性),并且回傳姓名、年齡和受教育水平三列
# iloc方法,切片上限無法取到
df1.iloc[1:4,[0,3,2]]
# loc方法,,通過名字索引
df1.loc[1:3,['name','age','edu']]
# ix方法,既可以指定位置索引,也可以指定名稱索引
df1.ix[1:3,[0,3,2]]
1.假如資料集沒有數值行號,而是具體的行名稱應如何篩選
對于iloc來說,不管什么形式的資料集都可以使用,他始終需要指定目標資料所在的位置索引;
loc就不能使用數值表示標簽欄,因為此時資料集的行標簽是姓名,所以需要寫入中間三行所對應的用戶姓名;
對于ix方法,即可以使用行索引如1:4,也可以使用行名稱表示,
另外,’:’表示取出資料集的所有變數,
# 將員工的姓名用作行標簽
df2=df1.set_index('name')
# 查看資料預覽
print(df2)
# iloc方法取出資料的中間三行
df2.iloc[1:4,:]
# loc方法取出資料的中間三行
df2.loc[['乙','丙','丁'],:]
# ix方法取出資料的中間三行
df2.ix[1:4,:]
2.顯然在實際操作中很少通過指定具體的行索引或行名稱盡心,而是基于列的條件運算式獲得目標子集,
條件篩選只能使用在loc和ix兩種方法中,
對變數的篩選loc方法必須指定具體的變數名稱,而ix方法既可以指定變數名稱,也可以指定變數所在的位置索引,
# 洗掉觀測,如洗掉age變數中所對應的缺失觀測
data3_new2=data3.loc[~data3['age'].isnul(),]
# 查看資料規模
print(data3_new2.shape)
#(2900,5)
注意:’~’表示邏輯非,如果不進行非操作,得到的將是缺失值所對應的行,
多表合并與連接314
SQL中多表合并采用UNION | UNION ALL;多表連接采用INNER JOIN | LEFT JOIN,
對Python來說,pandas模塊提供了concat函式和merge函式實作多表之間的合并和連接,
1.合并函式concat
pd.concat(objs,axis=0,join=’outer’,join_axes=None,ignore_index=False,keys=None)

如果縱向合并多個資料集,name和Name是不同的;
對于join_axes引數的使用,例如縱向合并兩個資料集df1和df2,可以寫成pd.concat([df1,df2]),
如果該引數等于[df1.index],則表示保留與df1行標簽值一樣的資料,但需要配合axis=1一起使用(即實作變數橫向合并操作);
如果等于[df1.columns],則保留與df1中所有變數值一樣的資料,但不需要添加axis=1的約束,
import pandas as pd
# 構造資料框
df1=pd.DataFrame({'name':['張三','李四','王二'],
'age':[21,25,22],
'gender':['男','女','男']
})
df2=pd.DataFrame({'name':['丁一','趙五'],
'age':[23,22],
'gender':['女','女']
})
# 資料集的縱向合并
df3=pd.concat([df1,df2], # 需將被合并的資料集組合到串列中,否則報錯
keys=['df1','df2'] # 借助于該引數區分不同的資料源
)
print(df3)
'''
name age gender
df1 0 張三 21 男
1 李四 25 女
2 王二 22 男
df2 0 丁一 23 女
1 趙五 22 女
'''
# 將第一列索引列轉換為變數
df3.reset_index(level=0, #level用于指定第幾個索引列需要轉換,0表示第一個索引列
inplace=True
)
# 變數重命名
df3.rename(columns={'level_0':'tab_name'},inplace=True)
# 重新調整行索引值
df3.index=range(df3.shape[0])
print(df3)
'''
tab_name name age gender
0 df1 張三 21 男
1 df1 李四 25 女
2 df1 王二 22 男
3 df2 丁一 23 女
4 df2 趙五 22 女
'''
2.連接函式merge
merge(left,right,how=’inner’,on=None,left_on=None,right_on=None,
left_index=False,right_index=False,sort=False,suffixes=(‘_x’,’_y’))

該函式最大的缺點是每次只能操作兩張資料表,如果有n張表需要連接,必須經過n-1次的merge函式使用,NaN為缺失值,表示無法匹配的值,
import pandas as pd
# 構造資料框
df3=pd.DataFrame({'id':[1,2,3,4,5],
'name':['張三','李四','王二','丁一','趙五'],
'age':[21,25,22,23,22],
'gender':['男','女','男','女','女']
})
df4=pd.DataFrame({'Id':[1,2,2,4,4,4,5],
'score':[83,81,87,75,86,74,88],
'kemu':['科目1','科目1','科目2','科目1','科目2','科目3','科目1']
})
df5=pd.DataFrame({'id':[1,3,5],'name':['張三','王二','趙五'],'income':[13500,18000,15000]})
# 首先將df3和df4連接,再將結果1 merge1和df5連接
merge1=pd.merge(left=df3,right=df4,how='left',left_on='id',right_on='Id')
print(merge1)
'''
id name age gender Id score kemu
0 1 張三 21 男 1.0 83.0 科目1
1 2 李四 25 女 2.0 81.0 科目1
2 2 李四 25 女 2.0 87.0 科目2
3 3 王二 22 男 NaN NaN NaN
4 4 丁一 23 女 4.0 75.0 科目1
5 4 丁一 23 女 4.0 86.0 科目2
6 4 丁一 23 女 4.0 74.0 科目3
7 5 趙五 22 女 5.0 88.0 科目1
'''
merge2=pd.merge(left=merge1,right=df5,how='right')
print(merge2)
'''
id name age gender Id score kemu income
0 1 張三 21 男 1.0 83.0 科目1 13500
1 3 王二 22 男 NaN NaN NaN 18000
2 5 趙五 22 女 5.0 88.0 科目1 15000
'''
資料的匯總319
pandas模塊既提供了Excel中的透視表功能,也提供了資料庫中的分組聚合功能,
1.透視表功能pivot_table函式
pd.pivot_table(data,values=None,index=None,columns=None,aggfunc=’mean’,
fill_value=None,margins=False,dropna=True,margins_name=’All’)

import pandas as pd
diamonds=pd.read_table(r'D:\Projects\Python\Doing\pythonProject\data\diamonds.csv',sep=',')
# 單個分組變數的均值統計
print(pd.pivot_table(data=diamonds,index='color',values='price',margins=True,margins_name='總計'))
'''
price
color
D 3169.954096
E 3076.752475
F 3724.886397
G 3999.135671
H 4486.669196
I 5091.874954
J 5323.818020
總計 3932.799722
'''
import pandas as pd
import numpy as np
diamonds=pd.read_table(r'D:\Projects\Python\Doing\pythonProject\data\diamonds.csv',sep=',')
# 兩個分組變數的列聯表
print(pd.pivot_table(data=diamonds,index='clarity',columns='cut',values='carat',aggfunc=np.size,margins=True,margins_name='總計'))
'''
cut Fair Good Ideal Premium Very Good 總計
clarity
I1 210.0 96.0 146.0 205.0 84.0 741.0
IF 9.0 71.0 1212.0 230.0 268.0 1790.0
SI1 408.0 1560.0 4282.0 3575.0 3240.0 13065.0
SI2 466.0 1081.0 2598.0 2949.0 2100.0 9194.0
VS1 170.0 648.0 3589.0 1989.0 1775.0 8171.0
VS2 261.0 978.0 5071.0 3357.0 2591.0 12258.0
VVS1 17.0 186.0 2047.0 616.0 789.0 3655.0
VVS2 69.0 286.0 2606.0 870.0 1235.0 5066.0
總計 1610.0 4906.0 21551.0 13791.0 12082.0 53940.0
'''
2.分組聚合操作,使用pandas模塊中的groupby方法和aggregate方法,
import pandas as pd
import numpy as np
diamonds=pd.read_table(r'D:\Projects\Python\Doing\pythonProject\data\diamonds.csv',sep=',')
# 通過groupby方法,指定分組變數
grouped=diamonds.groupby(by=['color','cut'])
# 對分組變數進行統計匯總
result=grouped.aggregate({'color':np.size,'carat':np.min,'price':np.mean,'face_width':np.max})
# print(result)
'''
color carat price face_width
color cut
D Fair 163 0.25 4291.061350 73.0
Good 662 0.23 3405.382175 66.0
Ideal 2834 0.20 2629.094566 62.0
Premium 1603 0.20 3631.292576 62.0
Very Good 1513 0.23 3470.467284 64.0
E Fair 224 0.22 3682.312500 73.0
Good 933 0.23 3423.644159 65.0
Ideal 3903 0.20 2597.550090 62.0
Premium 2337 0.20 3538.914420 62.0
Very Good 2400 0.20 3214.652083 65.0
F Fair 312 0.25 3827.003205 95.0
Good 909 0.23 3495.750275 66.0
Ideal 3826 0.23 3374.939362 63.0
Premium 2331 0.20 4324.890176 62.0
Very Good 2164 0.23 3778.820240 65.0
G Fair 314 0.23 4239.254777 76.0
Good 871 0.23 4123.482204 66.0
Ideal 4884 0.23 3720.706388 62.0
Premium 2924 0.23 4500.742134 62.0
Very Good 2299 0.23 3872.753806 66.0
H Fair 303 0.33 5135.683168 73.0
Good 702 0.25 4276.254986 65.0
Ideal 3115 0.23 3889.334831 62.0
Premium 2360 0.23 5216.706780 62.0
Very Good 1824 0.23 4535.390351 65.0
I Fair 175 0.41 4685.445714 70.0
Good 522 0.30 5078.532567 66.0
Ideal 2093 0.23 4451.970377 62.0
Premium 1428 0.23 5946.180672 62.0
Very Good 1204 0.24 5255.879568 65.0
J Fair 119 0.30 4975.655462 68.0
Good 307 0.28 4574.172638 65.0
Ideal 896 0.23 4918.186384 62.0
Premium 808 0.30 6294.591584 62.0
Very Good 678 0.24 5103.513274 63.0
'''
# 資料集重命名
result.rename(columns={'color':'counts','carat':'min_weight','price':'avg_price','face_width':'max_face_width'},
inplace=True)
print(result)
'''
counts min_weight avg_price max_face_width
color cut
D Fair 163 0.25 4291.061350 73.0
Good 662 0.23 3405.382175 66.0
Ideal 2834 0.20 2629.094566 62.0
Premium 1603 0.20 3631.292576 62.0
Very Good 1513 0.23 3470.467284 64.0
E Fair 224 0.22 3682.312500 73.0
Good 933 0.23 3423.644159 65.0
Ideal 3903 0.20 2597.550090 62.0
Premium 2337 0.20 3538.914420 62.0
Very Good 2400 0.20 3214.652083 65.0
F Fair 312 0.25 3827.003205 95.0
Good 909 0.23 3495.750275 66.0
Ideal 3826 0.23 3374.939362 63.0
Premium 2331 0.20 4324.890176 62.0
Very Good 2164 0.23 3778.820240 65.0
G Fair 314 0.23 4239.254777 76.0
Good 871 0.23 4123.482204 66.0
Ideal 4884 0.23 3720.706388 62.0
Premium 2924 0.23 4500.742134 62.0
Very Good 2299 0.23 3872.753806 66.0
H Fair 303 0.33 5135.683168 73.0
Good 702 0.25 4276.254986 65.0
Ideal 3115 0.23 3889.334831 62.0
Premium 2360 0.23 5216.706780 62.0
Very Good 1824 0.23 4535.390351 65.0
I Fair 175 0.41 4685.445714 70.0
Good 522 0.30 5078.532567 66.0
Ideal 2093 0.23 4451.970377 62.0
Premium 1428 0.23 5946.180672 62.0
Very Good 1204 0.24 5255.879568 65.0
J Fair 119 0.30 4975.655462 68.0
Good 307 0.28 4574.172638 65.0
Ideal 896 0.23 4918.186384 62.0
Premium 808 0.30 6294.591584 62.0
Very Good 678 0.24 5103.513274 63.0
'''
# 將行索引變換為資料框的變數
result.reset_index(inplace=True)
print(result)
'''
color cut counts min_weight avg_price max_face_width
0 D Fair 163 0.25 4291.061350 73.0
1 D Good 662 0.23 3405.382175 66.0
2 D Ideal 2834 0.20 2629.094566 62.0
3 D Premium 1603 0.20 3631.292576 62.0
4 D Very Good 1513 0.23 3470.467284 64.0
5 E Fair 224 0.22 3682.312500 73.0
6 E Good 933 0.23 3423.644159 65.0
7 E Ideal 3903 0.20 2597.550090 62.0
8 E Premium 2337 0.20 3538.914420 62.0
9 E Very Good 2400 0.20 3214.652083 65.0
10 F Fair 312 0.25 3827.003205 95.0
11 F Good 909 0.23 3495.750275 66.0
12 F Ideal 3826 0.23 3374.939362 63.0
13 F Premium 2331 0.20 4324.890176 62.0
14 F Very Good 2164 0.23 3778.820240 65.0
15 G Fair 314 0.23 4239.254777 76.0
16 G Good 871 0.23 4123.482204 66.0
17 G Ideal 4884 0.23 3720.706388 62.0
18 G Premium 2924 0.23 4500.742134 62.0
19 G Very Good 2299 0.23 3872.753806 66.0
20 H Fair 303 0.33 5135.683168 73.0
21 H Good 702 0.25 4276.254986 65.0
22 H Ideal 3115 0.23 3889.334831 62.0
23 H Premium 2360 0.23 5216.706780 62.0
24 H Very Good 1824 0.23 4535.390351 65.0
25 I Fair 175 0.41 4685.445714 70.0
26 I Good 522 0.30 5078.532567 66.0
27 I Ideal 2093 0.23 4451.970377 62.0
28 I Premium 1428 0.23 5946.180672 62.0
29 I Very Good 1204 0.24 5255.879568 65.0
30 J Fair 119 0.30 4975.655462 68.0
31 J Good 307 0.28 4574.172638 65.0
32 J Ideal 896 0.23 4918.186384 62.0
33 J Premium 808 0.30 6294.591584 62.0
34 J Very Good 678 0.24 5103.513274 63.0
'''
import matplotlib.pyplot as plt
import pandas as pd
sunspots=pd.read_csv(r'D:\Projects\Python\Doing\pythonProject\data\sunspots.csv')
# 繪制箱線圖(1.5倍的四分位差,如需繪制3倍的四分位差,只需調整whis引數)
plt.boxplot(x=sunspots.counts, # 指定繪制箱線圖的資料
whis=1.5, # 指定1.5倍的四分位差
widths=0.7, # 指定箱線圖的寬度為0.8
patch_artist=True, # 指定需要填充箱體顏色
showmeans=True, # 指定需要顯示均值
boxprops={'facecolor':'steelblue'}, # 指定箱體的填充色為鐵藍色
# 指定例外點的填充色、邊框色和大小
flierprops={'markerfacecolor':'red','markeredgecolor':'red','markersize':4},
# 指定均值點的標記符號(菱形)、填充色和大小
meanprops={'marker':'D','markerfacecolor':'black','markersize':4},
medianprops={'linestyle':'--','color':'orange'}, # 指定中位數的標記符號(虛線)和顏色
labels=[''] # 去除箱線圖的x軸刻度值
)
plt.show()

2.基于正態分布特性識別例外值——以某公司的支付轉化率分析為例
(1)正態分布的基本概念
根據正態分布的定義可知,資料點落在偏離均值正負1倍標準差(即δ值)內的概率為68.2%;資料點落在偏離均值正負2倍標準差內的概率為95.4%;資料點落在偏離均值正負3倍標準差內的概率為99.6%,
也就是說,如果資料點落在偏離均值正負2倍標準差之外的概率就不足5%,它屬于小概率事件,即認為這樣的資料點為例外點,同理,如果資料點落在偏離均值正負3倍標準差
之外的概率將會更小,可以認為這些資料點為極端例外點,
(2)plot函式
plot(x,y,linestyle,linewidth,color,marker,markersize,markeredgecolor,markerfactcolor,
markeredgewidth,label,alpha)
(3)正態分布實體——某公司的支付轉化率分析
如果待判斷的變數近似服從正態分布,建議選擇正態分布的參考線法識別例外點,否則使用分位數法識別例外點,
import matplotlib.pyplot as plt
import pandas as pd
pay_ratio=pd.read_excel(r'D:\Projects\Python\Doing\pythonProject\data\pay_ratio.xlsx')
# print(pay_ratio.head())
'''
date login pay ratio
0 2019-07-01 2234185 965957 0.432353
1 2019-07-02 1308983 598254 0.457038
2 2019-07-03 1395809 455764 0.326523
3 2019-07-04 1655896 522631 0.315618
4 2019-07-05 1141110 586891 0.514315
'''
# 繪制單條折線圖,并在折線圖的基礎上添加點圖
plt.plot(pay_ratio.date,pay_ratio.ratio, # x,y 軸資料
linestyle='-',linewidth=2,color='steelblue', # 設定折線型別、寬度和顏色
marker='o',markersize=4, # 往折線圖中添加圓點,設定點的大小
markeredgecolor='black',markerfacecolor='black' # 設定點的邊框色和填充色
)
# plt.show()
# 添加上下界的水平參考線(便于判斷例外點,如下面判斷極端例外點,只需將2改為3)
plt.axhline(y=pay_ratio.ratio.mean()-2*pay_ratio.ratio.std(),linestyle='--',color='gray')
plt.axhline(y=pay_ratio.ratio.mean()+2*pay_ratio.ratio.std(),linestyle='--',color='gray')
# 匯入模塊用于日期刻度的修改(因為默認格式下的日期刻度標簽并不是很友好)
import matplotlib as mpl
# 獲取圖的坐標資訊
ax=plt.gca()
# 設定日期的顯示格式
date_format=mpl.dates.DateFormatter("%m-%d")
ax.xaxis.set_major_formatter(date_format)
# 設定x軸每個刻度的間隔天數
xlocator=mpl.ticker.MultipleLocator(7)
ax.xaxis.set_major_locator(xlocator)
# 為了避免x軸刻度標簽的緊湊,將刻度標簽旋轉45°
plt.xticks(rotation=45)
# plt.show()
# 計算判斷例外點和極端例外點的臨界值
outlier_ll=pay_ratio.ratio.mean()-2*pay_ratio.ratio.std()
outlier_ul=pay_ratio.ratio.mean()+2*pay_ratio.ratio.std()
extreme_outlier_ll=pay_ratio.ratio.mean()-3*pay_ratio.ratio.std()
extreme_outlier_ul=pay_ratio.ratio.mean()+3*pay_ratio.ratio.std()
# 尋找例外點和極端例外點
print(pay_ratio.loc[(pay_ratio.ratio>outlier_ul)|(pay_ratio.ratio<outlier_ll),['date','ratio']])
'''
date ratio
10 2019-07-11 0.147000
32 2019-08-02 0.849452
34 2019-08-04 0.948245
45 2019-08-15 0.103448
63 2019-09-02 0.146569
67 2019-09-06 0.905321
79 2019-09-18 0.145246
89 2019-09-28 0.136075
'''
print(pay_ratio.loc[(pay_ratio.ratio>extreme_outlier_ul)|(pay_ratio.ratio<extreme_outlier_ll),['date','ratio']])
'''
date ratio
34 2019-08-04 0.948245
67 2019-09-06 0.905321
'''
3.例外值的處理方法
如果資料集中存在例外點,為避免例外點對后續分析或挖掘的影響,通常需要對例外點
做相應的處理,比較常見的處理辦法有如下幾種:
直接從資料集中洗掉例外點,
使用簡單數值(均值或中位數)或者距離例外值最近的最大值(最小值)替換例外值,也可以使用判斷例外值的臨界值替換例外值,
將例外值當作缺失值處理,伸用插補法估計例外值,或者根據例外值衍生出表示是否例外的啞變數,
轉載請註明出處,本文鏈接:https://www.uj5u.com/houduan/305694.html
標籤:python
