玩轉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)

工作中遇到常見問題及解決措施

  1. 讀入提示編碼問題。此時首先想到讀入文件的編碼格式,打開excel文件,選擇編碼為utf-8
  2. 讀入的第一個參數可以是相對路徑,此時直接為文件名,可以是絕對路徑。
  3. 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文件中,最經常出現的一個問題:

  1. 某些中文字元出現亂碼。解決措施,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] = -1

res = 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.

以上總結了:

  1. DataFrame的讀寫操作
  2. pd.iterrows返回的類型及生成器的原理
  3. DataFrame的兩個實例間的操作
  4. 一個實戰例子,應用了merge,掩碼去重,reset_index等.

下載源碼,請在公眾號後台回復: pandas

更多文章:

深度學習|大師之作,必是精品

演算法channel關鍵詞和文章索引

演算法優化|說說哨兵(sentinel value)

Numpy|需要信手拈來的功能

機器學習|快速排序思想求topk

機器學習|支持向量機參數求解

機器學習|K-Means演算法

圖演算法|Dijkstra演算法python實現

微信群: gz113097485

QQ交流群:646901659

演算法channel ∣原創乾貨分享

weixin.qq.com/r/cjhGXpj (二維碼自動識別)

長按,識別二維碼,加關注


推薦閱讀:

數據挖掘與可視化分析——以武漢市房價為例
《Python數據挖掘》筆記(四) 網路分析
你問我答之「關於人工智慧客服YiBot的一切」
SAS市場研究應用介紹:離散選擇分析
iPIN網的大數據來源及數據分析處理方式?

TAG:數據挖掘 | 數據分析 | Python |