標籤:

如何與pandas愉快地玩耍(二)

番茄醬煎蛋:如何與pandas愉快地玩耍(一)?

zhuanlan.zhihu.com圖標

前一篇文章介紹了pandas包的導入、數據讀取、查看數據、篩選數據、缺失值觀察及處理、重複值觀察與處理、列操作等內容,這篇文章繼續介紹我常用的pandas的其他「騷操作」。

排序

排序常用兩種方法,值排序sort_values()索引排序sort_index()

#根據C列的值升序排序df.sort_values(by=C, ascending=True, inplace=False) #根據C、D兩列的值降序排序df.sort_values(by=[C,D],ascending=False,inplace=False)#多列排序,名字升序排列,分數降序排列df.sort_values([name,score], ascending = [True,False], inplace=True)#根據索引升序排序df.sort_index()#根據索引降序排序df.sort_index(ascending=False)

分組

分組統計或者計算,對於數據分析中的細化研究有重要的價值,祭出大殺器 —— groupby()

#按照城市分組統計,如果不希望city作為index,可以as_index=Falsedf.groupby(by=city, as_index=True, sort=True)#多分組df.groupby([city,gender])#分組計算df.groupby([age]).aggregate(np.sum)#分組不同計算,比如對id計數、求平均滿意度、統計投訴個數df[satisfy] = df[satisfy].map({滿意:1.,不滿意:0.}) #先將滿意、不滿意分別轉換成1、0,這樣計算平均值就是平均滿意度df[complaints] = df[complaints].map({投訴:1.,不投訴:0.}) df.groupby(city).agg({id:size,satisfy:mean,complaints:sum})#先分組,後排序df.groupby(city).apply(lambda x: x.sort_values(score, ascending=False))#計算方法也可以自定義,使用匿名函數,例如返回不同性別的最高薪資與最低薪資的差值df.groupby(gender).salary.agg(lambda x:x.max()-x.min())

合併

很多情況下,數據的來源並不唯一,我們需要將來自多方的數據結合起來統一操作、分析,這就涉及到了數據的合併操作,常用三種方法merge,join,concat

在數據表列一致的情況下,我一般用concat

#默認axis=0,按行操作,俗稱「上下合併」,並且我希望index是可以自適應新生成的表,所以設置ignore_index=Truepd.concat([df1,df2],axis=0,join=outer,ignore_index=True) #比較相近的方法是append,類似於list的append()操作df1.append(df2)#axis=1,按列操作,俗稱「左右合併」,join=inner是內連接pd.concat([df1,df2],axis=1,join=inner)

連接merge有眾多的參數,可以進行灰常多不同的操作

pd.merge(left, right, how=inner, on=None, left_on=None, right_on=None, left_index=False, right_index=False, sort=True, suffixes=(_x, _y), copy=True, indicator=False, validate=None)

left形象的理解為即將位於左側的數據表,right即將位於右側的數據表,how有好幾種選擇,常用inner(內連接),outer(外連接),left(以左側數據為基準),right(以右側數據為基準)

on是兩表的連接key,就是兩表共同的列,並且是連接的依據,舉幾個栗子

#兩表在key上連接result = pd.merge(left, right, on=key)#也可以有多個keyresult = pd.merge(left, right, on=[key1, key2])

#以左表為基準,哪怕右表比較「短」(空值填充)或者右表比較「長」(多出的值捨棄)result = pd.merge(left, right, how=left, on=[key1, key2])

join的用法也差不多,可以參考mysql語句中的join使用理解,它的參數也使得它可以達到concat或者merge的部分效果

result = left.join(right)#外連接result = left.join(right, how=outer)#內連接result = left.join(right, how=inner)#指定keyresult = left.join(right, on=key)#指定多個keyresult = left.join(right, on=[key1, key2])

保存數據文件

在進行了一些列數據處理後,我們可以將結果推入資料庫,也可以導出保存為各種格式的數據文件,常見.txt格式,.csv格式,.xlsx格式等

df.to_csv(result.txt,sep= ,index=False,encoding=utf-8)df.to_csv(result.csv,sep=,,encoding=utf-8)df.to_excel(result.xlsx,index=False,encoding=gbk,float_format=%.2f)

保存涉及到幾個參數,分別說明一下,sep指分隔符,常用Tab鍵分隔符 ,或者逗號分隔符, ;index=False意思是保存的時候忽略 index,如果非有意義的index,建議把這項設為False;encoding則是編碼,有utf-8, gbk, gb2312, gb18030等

我在工作中還碰到一種情況,就是將多個不同類相似結構的數據表存入一個excel文件的多張sheets中,這時,再來一個神奇的包導入(女人愛「包」,取之有道,:)

from pandas import ExcelWriterwriter = pd.ExcelWriter(r./各地市來話量統計.xlsx) #開一個excel文件,準備寫入for c in ****: #配合for循環獲取到需要的數據表 #各種操作後,待保存 c.to_excel(writer,sheet_name=%s% c,index=False,encoding=gbk)writer.save()

存為excel文件的過程中,輸入超過11位數字時,會自動轉為科學計數的方式,我就經常碰到好好的時間變成了毫無意義的科學記數法,這時你一定要學會一種騷操作:

df[時間] = df[時間].astype(str) + #先轉為str類型,再加 分隔符

這樣,存儲好的excel文件中就不會有科學記數法的困擾了

字元串操作

在進行本文數據處理的時候,經常涉及字元串的操作,基礎處理方法就是python中的string的各種方法和re正則的各種方法,而我下面提到的方法是基於這兩者的,更方便快捷,並可以應用在dataframe中的

當我做關鍵詞匹配的時候,最常用的是series.str.contains(),比如

cond = df[conversation].str.contains(r投訴|法院)result = df.loc[cond]

這樣就可以匹配出conversation列中升級投訴的詞語,並篩選出相關數據記錄result

有的時候需要做文本分列,我用series.str.split(),比如下圖中的評論時間列,我只希望提取日期,「發表於」是沒有意義重複性文字,我可以先用split()方法分列,然後存為一張新的dataframe並重命名列,最後只保留「發表日期」列,再跟原表合併

pd.DataFrame(data[時間與發布人].str.split().tolist(),columns=[文章發表於,發表日期,發表時間,發布人])

有時候是數據來源的問題,導致文本內容中有各種雜亂的字元,比如爬蟲抓下來的網頁留言就可能含有<b><>類似的內容,在進行分析前,可以用series.str.replace()方法去掉

df[comment].str.replace(<b>|<>,)

還有處理句尾常見的
或者
,可以用series.str.strip()方法

df[comment].str.strip("
|
")

series的字元串方法還有很多,如有需要,請查詢文檔參考


推薦閱讀:

如何與pandas愉快地玩耍(一)

TAG:pandas包 |