玩轉Pandas,讓數據處理更easy系列3
01
回顧
前面介紹了Pandas最重要的兩個類:Series和DataFrame,講述了這兩種數據結構常用的屬性和操作,比如values,index, columns,索引,Series的增刪改查,DataFrame的增刪改查,Series實例填充到Pandas中,請參考:
玩轉Pandas,讓數據處理更easy系列1
玩轉Pandas,讓數據處理更easy系列2
02
讀入DataFrame實例
讀入的方式有很多種,可以是網路 html 爬蟲到數據,可以從excel, csv文件讀入的,可以是Json的數據,可以從sql庫中讀入,pandas提供了很方便的讀入這些文件的API,以讀入excel,csv文件為例:
#讀入excel文件
pd.read_excel(filename, Sheet=Sheet1, encoding=utf-8) #讀入csv文件pd.read_csv(filename, encoding=utf-8)
工作中遇到常見問題及解決措施
- 讀入提示編碼問題。此時首先想到讀入文件的編碼格式,打開excel文件,選擇編碼為utf-8
- 讀入的第一個參數可以是相對路徑,此時直接為文件名,可以是絕對路徑。
- read_excel是靜態方法,不是實例方法,所以pd模塊可以直接引用。
03
DataFrame實例寫入到excel和csv文件中
處理讀取,當然還有寫入,寫入API也很簡單,準備好了要寫入的DataFrame實例後,
#寫入excel文件
pd_data.to_excel(test.xls) #讀入csv文件pd_data.to_csv(test.csv)
構造一個pd_data, 然後寫入到excel文件中,
pd_data = pd.DataFrame([[1,2,3],[6,5,4]],columns=list(ABC))
pd_data.to_excel(pd_data_save.xls)
保存後的文件顯示如下:
保存到excel或csv文件中,最經常出現的一個問題:
- 某些中文字元出現亂碼。解決措施,to_csv方法的參數:encoding 設置為utf_8_sig. 這種方法應該是比較簡潔的解決辦法。
04
DataFrame遍歷Series
讀入或內存創建一個DataFrame實例:pd_data後,我們想根據某些條件,按照某個規則,對這些數據進行聚類,那麼,一種比較直接的辦法便是對pd_data遍歷:
for index, seri in pd_data.iterrows():
print(index = %d %(index)) # index: 行標籤 print(seri) # seri : Series實例
輸出結果如下,seri是一個Series實例
分享一個面試題,記得當年我面試時,二面的面試官直接問題pd_data.iterrows()返回的對象是什麼類型,不知道大家能說的上來嗎。用print(type( pd_data.iterrows() ))看下,返回結果 :generator. 中文名字叫發生器,這是個什麼東東? 它是list嗎?我們回顧下發生器的相關知識。
我們大家都熟悉列表,那麼創建一個列表有什麼問題呢?內存數量總是有限的,列表容量肯定不能超過內存大小。如果創建一個包含100萬個元素的列表,不僅佔用很大的存儲空間,並且假如我們僅僅需要訪問前面10%的元素,那後面絕大多數元素佔用的空間都白白浪費了。
如果列表元素中的元素可以按照某種演算法推算出來,那是否可以在循環過程中,推算出我們需要的一定數量的元素呢?這樣地話,我們就可以靈活地創建需要數量的list,從而節省大量的空間。在Python中,這種一邊循環一邊計算的機制,稱為生成器:generator。最難理解的就是generator和普通函數的執行流程不一樣,函數是順序執行,遇到return語句或者最後一行函數語句就返回。變成generator的函數,在每次調用next()的時候執行,遇到yield語句返回,再次執行時從上次返回的yield語句處繼續執行。
更詳細介紹可以參考:
Python|生成器
05
操作兩個DataFrame實例
以上闡述了DataFrame的最基本的操作,接下來,說一個好玩的功能。如果我已知一系列點的坐標,想求出任意兩點坐標之間的所有組合。該怎麼使用merge介面實現這個功能。
#已知4個點的x,y坐標
s=pd.DataFrame([[1,2.0, 3.0],[2,3.2,1.4],[3,9.0,0.7],[4,3.1,2.9]], columns=[no,x,y])s
如何用merge求出任意兩點間的所有組合呢? 結果集的個數應該為4*4=16行的矩陣,具體的實現腳本為:
s1 = s.copy() #複製一份出來
s1.columns = [s_no, s_x, s_y] #修改列的標籤s2 = s.copy()s2.columns = [e_no, e_x, e_y]
s1.loc[:,key] = -1 #添加一個內連接用的標籤s2.loc[:,key] = -1res = s1.merge(s2,left_on=key,right_on=key) #merge默認how=inner內連接方式res
這樣就求得了任意兩點之間的所有組合了,接下來,去掉添加的標籤key,以及消除s_no和e_no重複的行。
06
數據過濾
利用掩碼過濾數據是比較常用的,且簡潔高效的方法。實現以上過濾,我們可以使用這個技術。
首先,去掉標籤key這列,
res = res.drop(key,axis=1) #去掉標籤為key的列
先得到掩碼,條件為如下,返回的結果為一個Series實例,數據的類型為bool.
mask = res.loc[:,s_no]!=res.loc[:,e_no]
mask
接下來,使用如何拿這個Series實例得到最終的矩陣呢? 直接使用
res = res[ mask ]
# 或 res = res.loc[mask] 都可以
為什麼 loc[Series] 也可以呢? 再看下loc的API文檔,可以看出bool數組也是可以的,我們又知道Series是數組和標籤字典的組合。
Series.loc
Purely label-location based indexer for selection by label..loc[] is primarily label based, but may also be used with a boolean array.
去重後的結果如下:
大家一看,怎麼最後一行的標籤還是14啊,但是明顯行數少了啊, 原來行標籤斷開了,這不是我們想要的,還是要從0開始連續排序啊。怎麼辦?
07
重置索引
DataFrame和Series實例都有reset_index方法,這是與索引相關的方法,具體實施如下:
res = res.reset_index(drop=True)
res
看下參數drop的含義:
DataFrame.drop : boolean, default False
Do not try to insert index into dataframe columns.This resets the index to the default integer index.
以上總結了:
- DataFrame的讀寫操作
- pd.iterrows返回的類型及生成器的原理
- DataFrame的兩個實例間的操作
- 一個實戰例子,應用了merge,掩碼去重,reset_index等.
下載源碼,請在公眾號後台回復: pandas
更多文章:
深度學習|大師之作,必是精品
演算法channel關鍵詞和文章索引
演算法優化|說說哨兵(sentinel value)
Numpy|需要信手拈來的功能
機器學習|快速排序思想求topk
機器學習|支持向量機參數求解
機器學習|K-Means演算法
圖演算法|Dijkstra演算法python實現
微信群: gz113097485
QQ交流群:646901659
演算法channel ∣原創乾貨分享
http://weixin.qq.com/r/cjhGXpjE88WMrdw9921g (二維碼自動識別)
長按,識別二維碼,加關注
推薦閱讀:
※數據挖掘與可視化分析——以武漢市房價為例
※《Python數據挖掘》筆記(四) 網路分析
※你問我答之「關於人工智慧客服YiBot的一切」
※SAS市場研究應用介紹:離散選擇分析
※iPIN網的大數據來源及數據分析處理方式?