3-python數據分析-pandas高級操作之替換、映射、隨機抽樣、分組、高級數據聚合、數據加載、透視表、交叉表
替換操作 replace
替換操作可以同步作用于Series和DataFrame中
單值替換
普通替換: 替換所有符合要求的元素:to_replace=15,value=’e’
按列指定單值替換: to_replace={列標簽:替換值} value=’value’
多值替換
列表替換: to_replace=[] value=[]
字典替換(推薦) to_replace={to_replace:value,to_replace:value}
單值替換
df = DataFrame(data=np.random.randint(0,50,size=(7,5)))
#普通替換
df.replace(to_replace=7, value='seven')
#按列指定單值替換
df.replace(to_replace={0:7}, value='seven')
多值替換
#字典替換(推薦使用)
df.replace(to_replace={7:"seven",40:"四十"})#列表替換
df.replace(to_replace=[7,40],value=['seven','四十'])
映射操作 map
map是Series的方法,只能被Series調用
概念:創建一個映射關系列表,把values元素和一個特定的標簽或者字符串綁定(給一個元素值提供不同的表現形式)
創建一個df,兩列分別是姓名和薪資,然后給其名字起對應的英文名
dic ={'name':['jay','tom','jay'],'salary':[1000,2000,1000]
}
df= DataFrame(data=dic)
#給jay和tom起兩個中文名字#映射關系表:表明了映射關系
dic ={'jay':'張三','tom':'李四'}
df['c_name'] = df['name'].map(dic)
運算工具
Series的方法apply也可以像map一樣充當運算工具
定義一個方法將它放到map或apply方法中,會將Series中每個元素傳到函數中
apply充當運算工具效率要遠遠高于map,并且apply既可以用在Series也可以用在DataFrame
超過300部分的錢繳納50%的稅,計算每個人的稅后薪資
defafter_salary(s):if s > 300:return s - (s-300) * 0.5
returns
df['after_salary'] = df['salary'].map(after_salary)
df['salary'].apply(after_salary)
0650.0
1 1150.0
2 650.0Name: salary, dtype: float64
隨機抽樣 take
take()? task中的axis參數含義和drop系列的函數一致
np.random.permutation( n)? 返回0到n-1之間的亂序序列
df = DataFrame(data=np.random.randint(0,100,size=(100,3)),columns=['A','B','C'])
np.random.permutation(3) #返回0-2之間的亂序序列
array([2, 0, 1])#對原始數據進行打亂,打亂:是對索引打亂#對行列索引進行打亂并進行隨機抽樣抽取前10個
df.take(indices=np.random.permutation(3),axis=1).take(indices=np.random.permutation(100),axis=0)[0:10]
數據的分類處理 分組groupby
數據分類處理的核心:
groupby()函數可以進行分組
groups屬性可以查看分組情況
df = DataFrame({'item':['Apple','Banana','Orange','Banana','Orange','Apple'],'price':[4,3,3,2.5,4,2],'color':['red','yellow','yellow','green','green','green'],'weight':[12,20,50,30,20,44]})
#by 提供了分組條件,通過水果的種類進行分組
df.groupby(by='item')
#查看分組結果
df.groupby(by='item').groups
{'Apple': Int64Index([0, 5], dtype='int64'),'Banana': Int64Index([1, 3], dtype='int64'),'Orange': Int64Index([2, 4], dtype='int64')}
分組聚合
分組的目的就是為了后續對各個小組的聚合計算
計算每一種水果的平均價格
#計算每一種水果的平均價格
df.groupby('item').mean()['price']#不推薦使用上面這種,進行了多余計算,浪費運算成本,# 推薦使用下邊這種
df.groupby(by='item')['price'].mean()
item
Apple3.00Banana2.75Orange3.50Name: price, dtype: float64
將每一種水果的平均價格計算出來然后匯總到源數據中
mean_price = df.groupby('item').mean()['price']#直接將其轉成字典
mean_price_dic =mean_price.to_dict()
{'Apple': 3.0, 'Banana': 2.75, 'Orange': 3.5}#通過映射,映射到原數據
df['mean_price'] = df['item'].map(mean_price_dic)
求出每一種顏色水果的平均重量,將其匯總到源數據中
#通過color分組計算平均重量并轉成字典,通過color映射匯總到原數據
df['color_mean_weight'] = df['color'].map(df.groupby(by='color')['weight'].mean().to_dict())
高級數據聚合
使用groupby分組后,也可以使用transform和apply提供自定義函數實現更多的運算
df.groupby(‘item’)[‘price’].sum() <==> df.groupby(‘item’)[‘price’].apply(sum)
transform和apply都會進行運算,在transform或者apply中傳入函數即可
transform和apply也可以傳入一個lambda表達式
apply和transform的區別:
transform返回的結果是經過映射后的結果
apply返回的是沒有經過映射的結果
#定義的方法需要作用到運算工具中
def my_mean(s): #s是一組數據
sum =0for i ins:
sum+=ireturn sum /len(s)#transform和apply就是運算工具
#transform返回的是映射后的結果,直接可以匯總到原數據
df.groupby(by='item')['price'].transform(my_mean)
03.00
1 2.75
2 3.50
3 2.75
4 3.50
5 3.00Name: price, dtype: float64#apply返回的是沒有映射的結果,需要通過map映射才能匯總到原數據
df.groupby('item')['price'].apply(my_mean)
item
Apple3.00Banana2.75Orange3.50Name: price, dtype: float64
數據加載
讀取type-.txt文件數據
header 參數header默認是將數據第一行作為列索引,指定None后使用隱式索引
sep 參數sep指定數據通過什么分割
pd.read_csv('./data/type-.txt')
# 指定header等于None不使用第一行作列索引,使用隱式索引pd.read_csv('./data/type-.txt', header=None)
# 指定sep通過"-"分割數據pd.read_csv('./data/type-.txt', header=None, sep='-')
讀取數據庫中的數據
#連接數據庫,獲取連接對象
importsqlite3
conn= sqlite3.connect('./data/weather_2012.sqlite')#讀取庫表中的數據值, 參數(sql語句,連接對象)
pd.read_sql('select * from weather_2012', conn)#將數據寫入數據庫,參數(表名,連接對象)
text_df.to_sql('text_df', conn)
pd.read_sql('select * from text_df', conn)
透視表?pivot_table
透視表是一種可以對數據動態排布并且分類匯總的表格格式。在pandas中數據透視表被稱作pivot_table。
透視表的優點:
靈活性高,可以隨意定制你的分析計算要求
脈絡清晰易于理解數據
操作性強,報表神器
pivot_table有四個最重要的參數index、values、columns、aggfunc
數據讀取
#需要指定引擎和編碼,否則會報錯亂碼
df = pd.read_csv('./data/透視表-籃球賽.csv', engine='python', encoding='utf-8')
index參數
分類匯總的分類條件,每個pivot_table必須擁有一個index
#想看看哈登對陣同一對手在不同主客場下的數據,分類條件為對手和主客場
df.pivot_table(index=['對手','主客場'])
values參數
對計算的數據進行篩選
#如果我們只需要哈登在主客場和不同勝負情況下的得分、籃板與助攻三項數據
df.pivot_table(index=['主客場','勝負'],values=['得分','籃板','助攻'])
aggfunc參數
設置對數據聚合時使用的函數
當我們未設置aggfunc時,它默認aggfunc=’mean’計算均值
#想獲得哈登在主客場和不同勝負情況下的總得分、總籃板、總助攻時:#將aggfunc參數設為sum,就是對數據求和
df.pivot_table(index=['主客場','勝負'],values=['得分','籃板','助攻'], aggfunc='sum')
columns參數
設置列層次字段, 對values字段進行分類
#獲取所有隊主客場的總得分
df.pivot_table(index='主客場',values='得分', aggfunc='sum')
#查看主客場下的總得分的組成元素是誰
df.pivot_table(index='主客場', values='得分', aggfunc='sum', columns='對手')
#fill_value 將空值填充
df.pivot_table(index='主客場', values='得分', aggfunc='sum', columns='對手',fill_value=0)
交叉表?crosstab
是一種用于計算分組的特殊透視圖,對數據進行匯總
pd.crosstab(index,colums)
index:分組數據,交叉表的行索引
columns:交叉表的列索引
df = DataFrame({'sex':['man','man','women','women','man','women','man','women','women'],'age':[15,23,25,17,35,57,24,31,22],'smoke':[True,False,False,True,True,False,False,True,False],'height':[168,179,181,166,173,178,188,190,160]})
#求出各個性別抽煙的人數
pd.crosstab(index=df.smoke,columns=df.sex)
#求出各個年齡段抽煙人情況
pd.crosstab(index=df.age, columns=df.smoke)