python如何从一个dataframe提取相应的行组成一个新的dataframe_Python|专题(1)——数据处理常规操作集(1)...
大家好!好久不見!適逢國慶,先祝我親愛的祖國七十周年生日快樂!
這一系列文章是針對最近在實習中做的一些數據預處理操作的整理。我們希望通過它們,帶領大家了解和熟悉一些python做數據清洗,數據整合等的常見操作。
請注意我們這是專題文章,也就是說這一系列文章并不假設你對python是零基礎的。但是如果你和我一樣,也是一個數據科學中探索的小白,那么我希望你也能夠通過這些文章,在一個一個的數據處理的坑中爬起來,總結經驗,奮勇前行~
寫這一系列文章之前我也咨詢了老板的意見,也得到了他的同意。說這句話的意思是:所有這里涉及的操作,在數據分析中都是基礎,重要和容易踩坑的。所以即使你現在覺得它們難以理解,或者用不上,以后也大概率會碰到。還需要和大家說的是,為了防止泄露商業機密和業務材料,我們的數據集事先做過處理。
那么我們開始吧。沒有特殊介紹,我們都是使用Python3的。
1. 準備操作,裝包,導入
雖然這非常簡單,但我們還是提一下。凡是做數據預處理,都不可避免的用上這兩個包。
import如果你要做基本的可視化,那還需要這個包
import這句語法的意思就是:導入...包,并給它命名為np/pd。很多人經常在代碼中看到諸如np., pd. 這樣的前綴,意思就是調用numpy/pandas內的函數(還有一個說法叫方法)。
網絡上有非常多關于這兩個包的命令詳解,百度一下都有。至于如何安裝,各位只需要百度一下anaconda即可。anaconda本身就可以理解為是一個封裝好的python環境,里面已經事先有安裝好大部分必備的庫。
當然,你也可以使用
pip有一個情況是你電腦里的默認python不是anaconda內的那個(當你電腦里裝了不止一個py的時候,這種情況是完全有可能的)。除了環境變量的優先級調整法(具體的可以百度),還有一種方法我覺得更方便,就是打開anaconda的prompt。
這個Prompt可以理解為anaconda內自己的cmd (command line)。那么這個時候,下面這一行代碼
就可以自動把你想要安裝的包安裝到你的anaconda中。對于我這種py底層機理一竅不通的人來說,這已經夠用了,也很方便。雖然大部分情況都可以通過anaconda的可視化界面完成,但是我就碰到了tensorflow裝不上的情況,這個時候就只能采用上面那種方法了。
2. 讀取數據,創建數據框
配置有了,下一步自然是讀取數據,創建dataframe了。dataframe是pandas特有的一種數據結構,通俗理解就是一種計算機中存儲數據的結構,好吧這好像是一句廢話……
我截取了一部分我司的數據集(很顯然不可能是真實的,我在上面說過了),我們希望用它作為我們的例子,那么很顯然就需要構造一個dataframe來存儲它。常見的操作就是先構造一個字典,再轉換。具體如下
Table如果你運行正常的話,最后應該可以看到這樣的結果。
(這是在Jupyter Notebook上運行的,如果你在別的IDE上運行,顯示的樣子可能會有些不一樣)相信通過這個例子你也大概明白了什么是一個dataframe。
注意:代碼pd.DataFrame()中是首字母大寫的。
注意:你也許看到了這么一行代碼
[這是列表生成式。比方說它的目的就是生成1-9的一個列表。如果把它拆分一下,就是這么一個意思
Aappend方法就是在已有的列表之后再尾插一個元素。range是一個迭代器,具體用法百度。
很顯然我們不會一直這么錄入數據的,實際的數據集一般都是很大的。這個時候一般都會讀取已有的大的.csv格式的數據集。一般使用
Table比方說如果要讀取上面的那個數據集,那么你的csv文件用excel打開應該長這樣
.csv文件本質上是用逗號分隔的文本文件,所以沒有xls/xlsx文件那么大。當然了很多格式也無法保存在.csv文件中(比方說對一個數據標紅,加粗等,這些格式都無法保存)。如果你用記事本打開.csv,文件是長這樣的,樸實而無華。
那么多逗號是因為我手動刪除了很多列……
最后說幾個參數
- encoding: 轉換編碼。這個在讀取我司的數據的時候尤其重要,因為外面的數據一般都很臟(意思就是處理不當就是亂碼),所以強制為utf-8一定是墜吼的(最重要的是它對中文的支持非常好,所以數據看起來就很舒服)
- sep: 指定分隔符。因為有的文件可能會以tab為分隔符,這是為了防止出現一種情況就是表的內容本身也存在逗號(比方說有人手賤把2019/6/1改成2019,6,1)。當然一般的數據庫都沒這個處理,這個時候就只能手動來了……
- error_bad_lines: 這其實也是針對上面這種情況,因為如果識別逗號的時候發生錯誤,就會出現列名數和列數不一致的情況(比方說2019,6,1就會被拆成2019,6和1,本來是一個cell里的元素,硬是被拆到了3個cell里)。那么這個時候設置為False,系統就直接忽略這樣的行了。
在介紹下一個環節之前,我需要提一下的是我們的所有數據分析都會在本地進行。關于大數據架構的相關內容短時間并不會提到。
3. 數據拼接
雖然我們的數據非常小,但是實際情況下,數據因為過大很多時候在下載,提取的時候都會占用巨大的時間,因此很多時候我們都會分批次的下載。這種情況下我們自然需要把數據“拼”起來。如何去做呢?
Temppd.concat方法中的axis參數標志的是行和列。比方說這里axis=0意思就是按行拼接,axis=1就是按列拼接了。當然了,事先你需要把一些該拼起來的dataframe放在一個列表里。自然你還需要注意的是如果要按行拼接,那么自然兩個dataframe的列名,列數都是要相同的。另外一個同理。
當然,如果你是純拼接的,這樣子當然OK,但是很多時候,出現的情況是兩個待拼接的矩陣的列名有相同的地方。我們經常會使用SQL提取我們想要的特征,不可能一個原始的表就能提供我們想要的所有信息,這個時候要在不同的數據表中提取,就會涉及到左連接,右連接,內連接和外連接的情況。考慮到它們只是差別一個參數how,所以我們只解釋這四個名詞,就不舉例子了。
Definition 1: Left/Right/Inner/Outer Join左連接:表A, B連接只保留左表A的全部信息
右連接:表A, B連接只保留右表B的全部信息
內連接:表A, B連接只保留兩表重合的信息
外連接:表A, B連接,除兩表重合的信息外,列按序全部保留
詳細的可以參考下面這篇文章
Pandas DataFrame連接表,幾種連接方法的對比?www.jianshu.com4. 數據篩選
如果對幾個簡單的命令不熟悉,那么這也是一個臟活。這里我們單獨舉幾個例子。
首先來看簡單列表情況的。
Example 1:找出列表中大于等于3的數據,不改變表元素的順序
學過循環的人馬上開懷大笑,簡單!
B是,確實是一個不難的題目,可是Python有一個非常大的忌諱就是使用for循環。因為py的循環運行的很慢,所以實際我們的代碼中會盡量避免寫for循環(一般最多寫一重循環,二重的說什么也得改成一重2333),所以如果數據量大一點,到了GB, TB級別的,這代碼就該傻眼了。之前我們說的列表生成式其實本質上也是一種取代for循環的一個trick。
事實上,python有很多騷操作可以做一樣的事情。
Afilter函數就可以完成這個任務,需要說明的是匿名函數lambda。你可以理解為filter就是把匿名函數施加到了每一個列表的元素中,達到“篩選”的目的。
如果是針對dataframe呢?我們用上面那個列表舉例子。
A很多人可能看不明白這個操作,我們看一下拆解代碼后的結果。
A也就是說,我們做的事情就是先通過邏輯表達式判斷T/F,然后用T/F去做篩選。
這樣子的話,又一個問題來了,我可不可以直接這樣做。
A雖然R語言是可以的,但是Python里面這樣做是需要一些預處理的。需要注意的是,這個操作如果針對的是pandas里的Series結構,那么是沒有問題的。但是針對dataframe是8行的……好,那么我們可不可以自己造一個Series呢?
A其實Series就是一個僅有一列的dataframe(但是嚴格意義上來說這是不對的,兩個數據結構之間的方法,操作等是涇渭分明的)。
注意:一個很自然的聯想是,如果我希望選取一個區間,也就是說我需要兩個條件來制約。比方說我希望尋找值在[3, 4]的元素,那么有的人可能會寫成
A但事實上這是會報錯的。真正的寫法應該是這樣
A1這個謎題至今我不知道為什么……征個解了,希望出沒在評論區的大佬可以解答~
至于提到針對Series結構不太一樣的原因,我們之后再提,先放在這里。
除了這樣的邏輯關系篩選,其實還有一種篩選就是定點篩選。比方說下面這個業務需求。
Example 2:在A這個dataframe中挑選出值為2和3的所有元素。
注意這里的“值”的意思就是value,也就是除了index(最左邊那一列)外的其他列。
我們如何實現它呢?
A這里的.isin方法就需要我們提供一個列表,那么只要元素是這列表中的其中一個,就會被篩選出來。這個命令很多時候會很重要,比方說在推薦系統中,我們可能需要篩選出用戶中的高頻用戶,那么就可以通過邏輯關系篩選出這些用戶的ID,然后把ID的列表導出來,用這個列表去過濾原始的數據集,篩選出他們的銷售數據。
注意:你也許注意到了這個
A這個索引并沒有數量意義,這僅僅是因為A這個dataframe中,我們需要的那一列數據它的索引名是0(因為我們是直接把列表轉為了dataframe,所以默認索引為0)。也許你會想知道,那如果我希望知道dataframe的所有列名,怎么做呢?
A其實最重要的就是.columns這一個方法,其它的都是為了好看2333。另外這個也是只針對dataframe的(因為series是沒有header,也就是列名的)
你看,即使就是一個簡單的篩選,還有這么多細節的操作。
5. 數據整合
這一個部分主要是涉及到兩個操作,我們一個一個來看。
首先這第一個,其實是從這個業務需求來的。
Example 3:找出高頻用戶
你可能會想,這不是剛才已經提到過了嗎?請注意我們是在業界,而業界的數據庫中往往并沒有直接提供你算法所使用的數據集。比方說在我司,能夠知道的就只有按照時間排列的每一筆的銷售數據,但是如果你需要找到個人購買量,那就只能靠我們的整合代碼了。
我們顯然不會直接動用我司的數據集來演示。別忘了我們在第一個部分給大家手動創建了一個小的dataframe,我們就使用那個吧(變量名為Table)。
Table它的運行結果如下
這里我們用到的是groupby方法,也就是分組聚合。如果我們前面的列表生成式是對于每一個列表中的元素施加一個操作的話,這里的groupby就是針對dataframe中所選的那一列為“組名”來分組施加運算。比方說我們在原始的數據中,發現有2個人買了代號為S5的商品,那么你就可以看到,這兩個人就會對應兩個訂單編號,兩個日期,等等,而count方法就是計數的,所以這一行都是2。
就這些了嗎?鬧太套!我不要你覺得,我要我覺得,這個問題不需要商量,都聽我的,完全不止這些!比方說下面這個
Table注意:這一行代碼有兩個點可以說:
- 因為我們是對一列以字符串為數據類型的數據求得和,在字符串意義下就是拼接。所以你可以看到,有兩個人買了S5,所以這兩個人對應的商品代碼都是S5,拼在一起就變成了S5S5
- 你有沒有發現?如果我們事先提取我們所關心的那一列再進行求和,所對應的結果就變成了一個Series結構?還記得我們第四個部分說了什么嗎?沒有錯,在這個情況下,你可以發現,我們的數據篩選也會變的簡單很多。
所以我們可以把篩選與整合結合起來,就可以完成我們下面這個業務需求了。
Example 4:過濾出購買超過一單的人對應的所有訂單信息
我們還是使用Table這個數據集。
Temp雖然看上去四行代碼就完成我們的任務了,可是對于不熟練的人(比方說我),可能得摸索好幾天呢……
注意:如果你真的一步一步按照操作完成了,你會發現新的這個數據集它的索引并沒有變化,這樣的話如果你希望為數據添加特征(也就是添加幾列),可能會因為索引不匹配而報錯。所以一般推薦再加一行。
Result這樣就會重新從0開始按序排列索引。當然如果你把drop參數設置成了F,那么原始的索引會被作為一列值,其列名為index,新的索引依然是從0開始。
說完groupby我們來說一下透視表。透視表其實可以理解為一種雙向groupby。也就是說,它相當于選取了數據集的兩個特征做分組聚合。然后把這兩個特征的值作為兩個坐標軸。具體的我們可以參考Table數據集的這個例子。
Example 5:構造出一個以大分類為列,小分類為行的銷量數據。
它的代碼是這樣的
Resultpivot_table方法就是規定一列為新矩陣的列(index),一行為新矩陣的行(columns)。看似行列都有,結構完整,可是值是不是有點問題?你看最上方那個order_id也能明白發生了什么,是吧?沒有錯,使用透視表的時候,如果使用np.sum,那么它會默認選擇一個數類別(比方說int)的列進行操作。可能有的人會覺得可不可以使用np.count/pd.count,可是人家沒有這個函數啊……
我自己的解決方法是多拼接一列全部為1的數,然后再指定求和針對這一列。
Col可以看出來我們做了兩個改動,除了剛才說的拼接一列以外,還有一個就是我們多指定了函數中的values參數,這就可以指定在哪一列進行操作。你可以看到,新的數據集中值均正確,也沒有多出詭異的一個頭。
注意:pd.concat只可以拼接dataframe,所以如果是numpy的array,就需要做一步轉換了。為了方便我們索引,我們給它加了一個列名(.columns方法)
值得一提的函數是np.tile,它的機理是對已有的列表,矩陣進行不同軸上的復制粘貼。舉個例子,生成一個全1的長度為10列向量,其本質就是一個1,然后按列方向復制粘貼了10次,對吧?比方說下面這個例子
A你也可以看到,在numpy中構造矩陣的方式就是先構造一個向量,然后用reshape方法去重塑它的結構。這里np.tile這相當于一個小矩陣行列各擴充為原來的兩倍。感興趣的人可以試試把它轉為dataframe,看看它的索引,列名是什么?
最后關于透視表的其它操作可以參考這個官方文檔。
pandas.DataFrame.pivot_table - pandas 0.25.1 documentation?pandas.pydata.org6. 數據刪除
如果僅僅是說選取一個區間內的子集,這個我相信沒必要單獨拉出來說,直接用pandas內的數量索引就好。但是如果希望刪去指定行列呢?比方說剛才那個Table數據集,我們希望把那個多余的全1向量刪去,怎么辦?
Table這樣就可以復原了。注意這里axis = 1表示考慮列名,而不是索引。
7. 數據導出
顯然,我們還需要把我們做好處理的文件再導出為一個csv,這在py中也不難做到。
Resultheader和index就是表頭(列名)和索引,如果均選擇T,那么就會顯示出它們,否則就只會顯示出這些值所構成的矩陣了。
注意:在保存文件的時候要注意你選擇的工作路徑。因為如果路徑不是絕對路徑,那么保存的時候就會保存在你的工作路徑下。
小結
在這一節我們主要介紹了py中一些相對比較常見,但是又有一些小難度的實際數據分析中需要使用的python操作集合。所有的總結均是個人摸索的操作,因此具有很強的主觀性。我非常希望能夠有py大佬在評論區,或者私信,對不同的業務需求提出更好的解決方案!也希望和我一樣的數據分析新手能夠從中受益~
下一篇筆記傳送門:Python|專題(2)——數據處理常規操作集(2),數值計算的幾個加速技巧
——————————————————————————————————————
本專欄為我的個人專欄,也是我學習筆記的主要生產地。任何筆記都具有著作權,不可隨意轉載和剽竊。
個人微信公眾號:cha-diary,你可以通過它來獲得最新文章更新的通知。
《一個大學生的日常筆記》專欄目錄:筆記專欄|目錄
《GetDataWet》專欄目錄:GetDataWet|目錄
想要更多方面的知識分享嗎?可以關注專欄:一個大學生的日常筆記。你既可以在那里找到通俗易懂的數學,也可以找到一些雜談和閑聊。也可以關注專欄:GetDataWet,看看在大數據的世界中,一個人的心路歷程。我鼓勵和我相似的同志們投稿于此,增加專欄的多元性,讓更多相似的求知者受益~
總結
以上是生活随笔為你收集整理的python如何从一个dataframe提取相应的行组成一个新的dataframe_Python|专题(1)——数据处理常规操作集(1)...的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: csv文件怎么转成excel_怎么把wo
- 下一篇: 爬虫 404 try_无所不能的Pyth