說明
本書還是一本基礎入門的書,里面關於數據分析的思想對於初學者入門還是很有幫助的。
另外本書中的案例基本都是使用Excel與Python分別實現的,本筆記只記錄了Python的實現方式。
本書也很有趣味性,將數據分析比喻為做菜,用做菜的步驟類比數據分析的過程,理解起來很方便:
- 熟悉鍋——Python基礎知識+Pandas數據結構
- 准備食材——獲取數據源
- 淘米洗菜——數據預處理
- 菜品挑選——數據選擇
- 切配菜品——數值操作
- 開始烹調——數據運算
- 炒菜計時器——時間序列
- 菜品分類——數據分組/數據透視表
- 水果拼盤——多表拼接
- 盛菜裝盤——結果導出
- 菜品擺放——數據可視化
第1章 數據分析基礎
1.1 數據分析是什么
數據分析是指利用合適的工具在統計學理論的支撐下,對數據進行一定程度的預處理,然后結合具體業務分析數據,幫助相關業務部門監控、定位、分析、解決問題,從而幫助企業高效決策,提高經營效率,發現業務機會點,讓企業獲得持續競爭的優勢。
1.2 為什么要做數據分析
在做一件事情之前我們首先得弄清楚為什么要做,或者說做了這件事以后有什么好處,這樣我們才能更好地堅持下去。
啤酒和尿布的問題大家應該都聽過,如果沒有數據分析,相信大家是怎么也不會發現買尿布的人一般也會順帶買啤酒,現在各大電商網站都會賣各種套餐,相關商品搭配銷售能大大提高客單價,增加收益,這些套餐的搭配都是基於歷史用戶購買數據得出來的。如果沒有數據分析,可能很難想到要把商品搭配銷售,或者不知道該怎么搭配。
數據分析可以把隱藏在大量數據背后的信息提煉出來,總結出數據的內在規律。代替了以前那種拍腦袋、靠經驗做決策的做法,因此越來越多的企業重視數據分析。具體來說,數據分析在企業日常經營分析中有三大作用,即現狀分析、原因分析、預測分析。
現狀分析
現狀分析可以告訴你業務在過去發生了什么,具體體現在兩個方面。
第一,告訴你現階段的整體運營情況,通過各個關鍵指標的表現情況來衡量企業的運營狀況,掌握企業目前的發展趨勢。
第二,告訴你企業各項業務的構成,通常公司的業務並不是單一的,而是由很多分支業務構成的,通過現狀分析可以讓你了解企業各項分支業務的發展及變動情況,對企業運營狀況有更深入的了解。
現狀分析一般通過日常報表來實現,如日報、周報、月報等形式。
例如,電商網站日報中的現狀分析會包括訂單數、新增用戶數、活躍率、留存率等指標同比、環比上漲/下跌了多少。如果將公司的業務划分為華北、東北、華中、華東、華南、西南、西北幾個片區,那么通過現狀分析,你可以很清楚地知道哪些區域做得比較好,哪些區域做得比較差。
原因分析
原因分析可以告訴你某一現狀為什么會存在。
經過現狀分析,我們對企業的運營情況有了基本了解,知道哪些指標呈上升趨勢,哪些指標呈下降趨勢,或者是哪些業務做得好,哪些做得不好。但是我們還不知道那些做得好的業務為什么會做得好,做得差的業務的原因又是什么?
找原因的過程就是原因分析。
原因分析一般通過專題分析來完成,根據企業運營情況選擇針對某一現狀進行原因分析。
例如,在某一天的電商網站日報中,某件商品銷量突然大增,那么就需要針對這件銷量突然增加的商品做專題分析,看看是什么原因促成了商品銷量大增。
預測分析
預測分析會告訴你未來可能發生什么。
在了解企業經營狀況以后,有時還需要對企業未來發展趨勢做出預測,為制訂企業經營目標及策略提供有效的參考與決策依據,以保證企業的可持續健康發展。
例如,通過上述的原因分析,我們就可以有針對性地實施一些策略。比如通過原因分析,我們得知在台風來臨之際面包的銷量會大增,那么我們在下次台風來臨之前就應該多准備一些面包,同時為了獲得更多的銷量做一系列准備。
1.3 數據分析究竟在分析什么
數據分析的重點在分析,而不在工具,那么我們究竟該分析什么呢?
總體概覽指標
總體概覽指標又稱統計絕對數,是反映某一數據指標的整體規模大小,總量多少的指標。
例如,當日銷售額為60萬元,當日訂單量為2萬,購買人數是1.5萬人,這些都是概覽指標,用來反映某個時間段內某項業務的某些指標的絕對量。
例如,當日銷售額為60萬元,當日訂單量為2萬,購買人數是1.5萬人,這些都是概覽指標,用來反映某個時間段內某項業務的某些指標的絕對量。
對比性指標
對比性指標是說明現象之間數量對比關系的指標,常見的就是同比、環比、差這幾個指標。
同比是指相鄰時間段內某一共同時間點上指標的對比;
環比就是相鄰時間段內指標的對比;
差就是兩個時間段內的指標直接做差;
差的絕對值就是兩個時間段內指標的變化量。
例如,2018年和2017年是相鄰時間段,那么2018年的第26周和2017年的第26周之間的對比就是同比,而2018年的第26周和第25周的對比就是環比。
集中趨勢指標
集中趨勢指標是用來反映某一現象在一定時間段內所達到的一般水平,通常用平均指標來表示。平均指標分為數值平均和位置平均。例如,某地的平均工資就是一個集中趨勢指標。
數值平均是統計數列中所有數值平均的結果,有普通平均數和加權平均數兩種。普通平均的所有數值的權重都是1,而加權平均中不同數值的權重是不一樣的,在算平均值時不同數值要乘以不同的權重。
假如你要算一年中每月的月平均銷量,這個時候一般就用數值平均,直接把12個月的銷量相加除以12即可。
假如你要算一個人的平均信用得分情況,由於影響信用得分的因素有多個,而且不同因素的權重占比是不一樣的,這個時候就需要使用加權平均。
位置平均/眾數/中位數的概念
位置平均是基於某個特殊位置上的數或者普遍出現的數,即用出現次數最多的數值來作為這一系列數值的整體一般水平。
基於位置的指標最常用的就是中位數,基於出現次數最多的指標就是眾數。
眾數是一系列數值中出現次數最多的數值,是總體中最普遍的值,因此可以用來代表一般水平。如果數據可以分為多組,則為每組找出一個眾數。注意,眾數只有在總體內單位足夠多時才有意義。
中位數是將一系列值中的每一個值按照從小到大順序排列,處於中間位置的數值就是中位數。因為處於中間位置,有一半變量值大於該值,一半小於該值,所以可以用這樣的中等水平來表示整體的一般水平。
離散程度指標
離散程度指標是用來表示總體分布的離散(波動)情況的指標,如果這個指標較大,則說明數據波動比較大,反之則說明數據相對比較穩定。
全距(又稱極差)、方差、標准差等幾個指標用於衡量數值的離散情況。
全距
全距:由於平均數讓我們確定一批數據的中心,但是無法知道數據的變動情況,因此引入全距。
全距的計算方法是用數據集中最大數(上界)減去數據集中最小數(下界)。
全距存在的問題主要有兩方面:
- 問題1:容易受異常值影響。
- 問題2:全距只表示了數據的寬度,沒有描述清楚數據上下界之間的分布形態。
對於問題1我們引入四分位數的概念。四分位數將一些數值從小到大排列,然后一分為四,最小的四分位數為下四分位數,最大的四分位數為上四分位數,中間的四分位數為中位數。
對於問題2我們引入了方差和標准差兩個概念來衡量數據的分散性。
方差與標准差
方差是每個數值與均值距離的平方的平均值,方差越小說明各數值與均值之間的差距越小,數值越穩定。
標准差是方差的開方,表示數值與均值距離的平均值。
相關性指標
上面提到的幾個維度是對數據整體的情況進行描述,但是我們有的時候想看一下數據整體內的變量之間存在什么關系,一個變化時會引起另一個怎么變化,我們把用來反映這種關系的指標叫做相關系數,相關系數常用r來表示。

其中,Cov(X,Y)為X與Y的協方差,Var[X]為X的方差,Var[Y]為Y的方差。
關於相關系數需要注意以下幾點。
- 相關系數r的范圍為[-1,1]。
- r的絕對值越大,表示相關性越強。
- r的正負代表相關性的方向,正代表正相關,負代表負相關。
相關關系與因果關系
相關關系不等於因果關系,相關關系只能說明兩件事情有關聯,而因果關系是說明一件事情導致了另一件事情的發生,不要把這兩種關系混淆使用。
例如,啤酒和尿布是具有相關關系的,但是不具有因果關系;而流感疾病和關鍵詞檢索量上漲是具有因果關系的。
在實際業務中會遇到很多相關關系,但是具有相關關系的兩者不一定有因果關系,一定要注意區分。
1.4 數據分析的常規流程
數據分析是借助合適的工具去幫助公司發現數據背后隱藏的信息,對這些隱藏的信息進行挖掘,從而促進業務發展。基於此,可以將數據分析分為以下幾個步驟:

熟悉工具
數據分析是利用合適的工具和合適的理論挖掘隱藏在數據背后的信息,因此數據分析的第一步就是要熟悉工具。工欲善其事,必先利其器,只有熟練使用工具,才能更好地處理數據、分析數據。
明確目的
做任何事情都要目的明確,數據分析也一樣,首先要明確數據分析的目的,即希望通過數據分析得出什么。例如,希望通過數據分析發現流失用戶都有哪些特征,希望通過數據分析找到銷量上漲的原因。
獲取數據
目的明確后我們就要獲取數據,在獲取數據之前還需要明確以下幾點:
- 需要什么指標。
- 需要什么時間段的數據。
- 這些數據都存在哪個數據庫或哪個表中。
- 怎么提取,是自己寫Sql還是可以直接從ERP系統中下載。
熟悉數據
拿到數據以后,我們要去熟悉數據,熟悉數據就是看一下有多少數據,這些數據是類別型還是數值型的;每個指標大概有哪些值,這些數據能不能滿足我們的需求,如果不夠,那么還需要哪些數據。
獲取數據和熟悉數據是一個雙向的過程,當你熟悉完數據以后發現當前數據維度不夠,那就需要重新獲取;當你獲取到新的數據以后,需要再去熟悉,所以獲取數據和熟悉數據會貫穿在整個數據分析過程中。
處理數據
獲取到的數據是原始數據,這些數據中一般會有一些特殊數據,我們需要對這些數據進行提前處理,常見的特殊數據主要有以下幾種:
- 異常數據。
- 重復數據。(需要刪除)
- 缺失數據。
- 測試數據。(需要刪除)
對於重復數據、測試數據我們一般都是做刪除處理的。
對於缺失數據,如果缺失比例高於30%,那么我們會選擇放棄這個指標,即做刪除處理。而對於缺失比例低於30%的指標,我們一般進行填充處理,即使用0、均值或者眾數等進行填充。
對於異常數據,需要結合具體業務進行處理,如果你是一個電商平台的數據分析師,你要找出平台上的刷單商戶,那么異常值就是你要重點研究的對象了;假如你要分析用戶的年齡,那么一些大於100或者是小於0的數據,就要刪除。
分析數據
分析數據主要圍繞上節介紹的數據分析指標展開。在分析過程中經常采用的一個方法就是下鑽法,例如當我們發現某一天的銷量突然上漲/下滑時,我們會去看是哪個地區的銷量上漲/下滑,進而再看哪個品類、哪個產品的銷量出現上漲/下滑,層層下鑽,最后找到問題產生的真正原因。
得出結論
通過分析數據,我們就可以得出結論。
驗證結論
有的時候即使是通過數據分析出來的結論也不一定成立,所以我們要把數據分析和實際業務相聯系,去驗證結論是否正確。
例如,做新媒體數據分析,你通過分析發現情感類文章的點贊量、轉發量更高,這只是你的分析結論,但是這個結論正確嗎?你可以再寫幾篇情感類文章驗證一下。
展示結論
我們在分析出結論,並且結論得到驗證以后就可以把這個結論分享給相關人員,例如領導或者業務人員。這個時候就需要考慮如何展示結論,以什么樣的形式展現,這就要用到數據可視化了。
1.5 數據分析工具:Excel與Python
同一個操作可以使用不同的工具實現,不同工具的實現方式是不一樣的,Excel 是通過鼠標點選的方式來操作數據,而 Python需要通過具體的代碼來操作數據。雖然兩者的操作方式是不一樣的,但都可以達到導入外部數據這一操作的目的。Python在數據分析領域只不過是和Excel類似的一個數據分析工具而已。
本書的編寫都是按照這種方式進行的,針對數據分析中的每一個操作,分別用Excel和Pyhon對比實現。
第2章 Python基礎知識
(略)
第3章 Pandas數據結構
前面講了Python的基礎知識,從這一章開始進入正式的數據分析過程中,主要講述每個數據分析過程都會用到什么操作,這些操作用 Excel 是怎么實現的,如果用Python,那么代碼應該怎么寫。
import pandas as pd
import numpy as np
import matplotlib.pyplot as plt
3.1 Series數據結構
Series是什么
Series是一種類似於一維數組的對象,由一組數據及一組與之相關的數據標簽(即索引)組成。

上面這樣的數據結構就是Series,第一列數字是數據標簽,第二列是具體的數據,數據標簽與數據是一一對應的。
上面的數據用Excel表展示如下表所示。

創建一個Series
創建一個Series利用的方法是pd.Series(),通過給Series()方法傳入不同的對象即可實現。
傳入一個列表
如果只是傳入一個列表不指定數據標簽,那么Series會默認使用從0開始的數做數據標簽,上面的0、1、2、3就是默認的數據標簽。
# -*- coding:utf-8 -*-
import pandas as pd
s1 = pd.Series(["a","b","c"])
print(s1)
"""
0 a
1 b
2 c
dtype: object
"""
指定索引
直接傳入一個列表會使用默認索引,也可以通過設置index參數來自定義索引。
# -*- coding:utf-8 -*-
import pandas as pd
s1 = pd.Series(["whw","naruto","sasuke"],index=["a","b","c"])
print(s1)
"""
a whw
b naruto
c sasuke
dtype: object
"""
傳入一個字典
也可以將數據與數據標簽以key:value(字典)的形式傳入,這樣字典的key值就是數據標簽,value就是數據值。
# -*- coding:utf-8 -*-
import pandas as pd
s1 = pd.Series({"a":"whw","b":"sakura","c":"hahaha"})
print(s1)
"""
a whw
b sakura
c hahaha
dtype: object
"""
利用index方法獲取Series的索引
獲取一組數據的索引是比較常見的需求,直接利用 index 方法就可以獲取 Series的索引值,代碼如下所示。
# -*- coding:utf-8 -*-
import pandas as pd
s1 = pd.Series({"a":"whw","b":"sakura","c":"hahaha"})
print(s1.index) # Index(['a', 'b', 'c'], dtype='object')
print(s1.index[0]) # a
print(s1.index[1]) # b
print(s1.index[2]) # c
# 超出范圍會報錯
print(s1.index[3]) # IndexError: index 3 is out of bounds for axis 0 with size 3
利用values方法獲取Series的值
與索引值對應的就是獲取Series的值,使用的方法是values方法。
# -*- coding:utf-8 -*-
import pandas as pd
s1 = pd.Series({"a":"whw","b":"sakura","c":"hahaha"})
print(s1.values,type(s1.values)) # ['whw' 'sakura' 'hahaha'] <class 'numpy.ndarray'>
print(s1.values[1]) # sakura
3.2 DataFrame表格型數據結構
DataFrame是什么
Series是由一組數據與一組索引(行索引)組成的數據結構,而DataFrame是由一組數據與一對索引(行索引和列索引)組成的表格型數據結構。
之所以叫表格型數據結構,是因為DataFrame的數據形式和Excel的數據存儲形式很相近,接下來的章節主要圍繞DataFrame這種表格型數據結構展開。下面就是一個簡單的DataFrame數據結構。

上面這種數據結構和Excel的數據結構很像,既有行索引又有列索引,由行索引和列索引確定唯一值。如果把上面這種結構用Excel表展示如下表所示。

創建一個DataFrame
創建DataFrame使用的方法是pd.DataFrame(),通過給DataFrame()方法傳入不同的對象即可實現。
傳入一個列表
只傳入一個單一列表時,該列表的值會顯示成一列,且行和列都是從0開始的默認索引。
# -*- coding:utf-8 -*-
import pandas as pd
df1 = pd.DataFrame(["aa","bb","cc"])
print(df1)
"""
0
0 aa
1 bb
2 cc
"""
傳入一個嵌套列表 *
當傳入一個嵌套列表時,會根據嵌套列表數顯示成多列數據,行、列索引同樣是從0開始的默認索引。列表里面嵌套的列表也可以換成元組。
# -*- coding:utf-8 -*-
import pandas as pd
df1 = pd.DataFrame([["aa","A"],["bb","B"],["cc","C"]])
print(df1)
"""
0 1
0 aa A
1 bb B
2 cc C
"""
指定行、列的索引 *
如果只給DataFrame()方法傳入列表,DataFrame()方法的行、列索引都是默認值,則可以通過設置columns參數自定義列索引,設置index參數自定義行索引。
# -*- coding:utf-8 -*-
import pandas as pd
# 設置列索引
df31 = pd.DataFrame([["aa","A"],["bb","B"],["cc","C"]],columns=["小寫","大寫"])
print(df31)
"""
小寫 大寫
0 aa A
1 bb B
2 cc C
"""
# 設置行索引
df41 = pd.DataFrame([["aa","A"],["bb","B"],["cc","C"]],index=["一","二","三"])
print(df41)
"""
0 1
一 aa A
二 bb B
三 cc C
"""
# 同時設置行 列索引
df51 = pd.DataFrame([["aa","A"],["bb","B"],["cc","C"]],
columns=["小寫","大寫"],
index=["一","二","三"])
print(df51)
"""
小寫 大寫
一 aa A
二 bb B
三 cc C
"""
傳入一個字典
直接以字典的形式傳入DataFrame時,字典的key值就相當於列索引,這個時候如果沒有設置行索引,行索引還是使用從0開始的默認索引,同樣可以使用index參數自定義行索引,代碼如下:
# -*- coding:utf-8 -*-
import pandas as pd
# 字典的key是列索引 行索引不指定的話默認從0開始 也可以指定行索引
data = pd.DataFrame({"name":["whw","naruto","sasuke"],"age":[18,29,22]},
index=["一","二","三"])
print(data)
"""
name age
一 whw 18
二 naruto 29
三 sasuke 22
"""
獲取DataFrame行、列索引
使用columns方法獲取DataFrame的列索引:
使用index方法獲取DataFrame的行索引:
# -*- coding:utf-8 -*-
import pandas as pd
# 字典的key是列索引 行索引不指定的話默認從0開始 也可以指定行索引
data = pd.DataFrame({"name":["whw","naruto","sasuke"],"age":[18,29,22]},
index=["一","二","三"])
# 列索引
print(data.columns) # Index(['name', 'age'], dtype='object')
# 行索引
print(data.index) # Index(['一', '二', '三'], dtype='object')
獲取DataFrame的值
獲取DataFrame的值就是獲取DataFrame中的某些行或列,有關行、列的選擇在第6章會有詳細講解。
第4章 獲取數據源
4.1 導入外部數據(.xlsx文件)
導入數據主要用到的是Pandas里的read_x()方法,x表示待導入文件的格式。
導入.xlsx文件
在 Excel 中導入.xlsx 格式的文件很簡單,雙擊打開即可。在 Python 中導入.xlsx文件的方法是read_excel()。
test.xlsx中的內容如下:

基本導入
不指定sheet_name參數時,那么默認導入的都是第一個Sheet的文件
# -*- coding:utf-8 -*-
import pandas as pd
# 讀取excel中的內容 路徑放在了桌面下
df = pd.read_excel(r"~/Desktop/test.xlsx")
print(df)
"""
編號 姓名 年齡 注冊日期
0 A1 whw 22 2020-10-12
1 A2 naruto 23 2020-10-12
2 A3 sasuke 24 2020-10-12
"""
指定導入哪個Sheet
.xlsx格式的文件可以有多個Sheet,你可以通過設定sheet_name參數來指定要導入哪個Sheet的文件。
# -*- coding:utf-8 -*-
import pandas as pd
### 方法一 指定Sheet的名稱
df = pd.read_excel(r"~/Desktop/test.xlsx",sheet_name="Sheet1")
print(df)
"""
編號 姓名 年齡 注冊日期
0 A1 whw 22 2020-10-12
1 A2 naruto 23 2020-10-12
2 A3 sasuke 24 2020-10-12
"""
### 方法二 傳入Sheet的順序 —— 從0開始計數 導入第1個Sheet
df2 = pd.read_excel(r"~/Desktop/test.xlsx",sheet_name=0)
print(df2)
"""
編號 姓名 年齡 注冊日期
0 A1 whw 22 2020-10-12
1 A2 naruto 23 2020-10-12
2 A3 sasuke 24 2020-10-12
"""
指定行索引
將本地文件導入DataFrame時,行索引使用的從0開始的默認索引,可以通過設置index_col參數來設置。
# -*- coding:utf-8 -*-
import pandas as pd
# 指定行索引 —— 就是將那一列當作行索引 —— 將第2列作為行索引(索引從0開始)
df = pd.read_excel(r"~/Desktop/test.xlsx",sheet_name="Sheet1",index_col=1)
print(df)
"""
編號 年齡 注冊日期
姓名
whw A1 22 2020-10-12
naruto A2 23 2020-10-12
sasuke A3 24 2020-10-12
"""
指定列索引
將本地文件導入DataFrame時,默認使用源數據表的第一行作為列索引,也可以通過設置header參數來設置列索引。
header參數值默認為0,即用第一行作為列索引;也可以是其他行,只需要傳入具體的那一行即可;也可以使用默認從0開始的數作為列索引。
# -*- coding:utf-8 -*-
import pandas as pd
# 使用第一行作為列索引
df = pd.read_excel(r"~/Desktop/test.xlsx",sheet_name=0,header=0)
print(df)
"""
編號 姓名 年齡 注冊日期
0 A1 whw 22 2020-10-12
1 A2 naruto 23 2020-10-12
2 A3 sasuke 24 2020-10-12
"""
# 使用第三行作為列索引
df2 = pd.read_excel(r"~/Desktop/test.xlsx",sheet_name=0,header=2)
print(df2)
"""
A2 naruto 23 2020-10-12 00:00:00
0 A3 sasuke 24 2020-10-12
"""
# 使用默認從0開始的數作為列索引
df3 = pd.read_excel(r"~/Desktop/test.xlsx",sheet_name=0,header=None)
print(df3)
"""
0 1 2 3
0 編號 姓名 年齡 注冊日期
1 A1 whw 22 2020-10-12 00:00:00
2 A2 naruto 23 2020-10-12 00:00:00
3 A3 sasuke 24 2020-10-12 00:00:00
"""
指定導入列
有的時候本地文件的列數太多,而我們又不需要那么多列時,我們就可以通過設定usecols參數來指定要導入的列。
# -*- coding:utf-8 -*-
import pandas as pd
# 指定導入的列
df = pd.read_excel(r"~/Desktop/test.xlsx",usecols=[1,3])
print(df)
"""
姓名 注冊日期
0 whw 2020-10-12
1 naruto 2020-10-12
2 sasuke 2020-10-12
"""
4.1 導入外部數據(.csv文件)
在 Excel 中導入.csv 格式的文件和打開.xlsx 格式的文件一樣,雙擊即可。
tt.csv文件中的內容如下:

在 Excel 中導入.csv 格式的文件和打開.xlsx 格式的文件一樣,雙擊即可。而在Python中導入.csv文件用的方法是read_csv()。
直接導入
# -*- coding:utf-8 -*-
import pandas as pd
# 直接指定文件路徑即可
df = pd.read_csv(r"~/Desktop/tt.csv")
print(df)
"""
name age gender
0 whw 19 male
1 naruto 22 male
2 sakura 22 female
"""
指明分隔符號
在Excel和DataFrame中的數據都是很規整的排列的,這都是工具在后台根據某條規則進行切分的。read_csv()默認文件中的數據都是以逗號分開的,但是有的文件不是用逗號分開的,這個時候就需要人為指定分隔符號,否則就會報錯。
將之前的文件的分隔符按照 | 分隔:

如果用默認的逗號作為分隔符號,我們看到所有的數據還是一個整體,並沒有被分開~
# -*- coding:utf-8 -*-
import pandas as pd
# 默認使用逗號分隔,如果原文件不是使用逗號分隔的就會出問題:沒有將文件內容分開
df = pd.read_csv(r"~/Desktop/tt.csv")
print(df)
"""
name|age|gender
0 whw|19|male
1 naruto|22|male
2 sakura|22|female
"""
指定分隔符號試試:
# -*- coding:utf-8 -*-
import pandas as pd
# 指定分隔符號
df = pd.read_csv(r"~/Desktop/tt.csv",sep="|")
print(df)
"""
name age gender
0 whw 19 male
1 naruto 22 male
2 sakura 22 female
"""
常見的分隔符號除了逗號、空格,還有制表符(\t)。
指明讀取行數
假設現在有一個幾百兆的文件,你想了解一下這個文件里有哪些數據,那么這個時候你就沒必要把全部數據都導入,你只要看到前面幾行即可,因此只要設置nrows參數即可。
# -*- coding:utf-8 -*-
import pandas as pd
# 指定讀取的行數
df = pd.read_csv(r"~/Desktop/tt.csv",sep="|",nrows=1)
print(df)
"""
name age gender
0 whw 19 male
"""
指定編碼格式
Python用得比較多的兩種編碼格式是UTF-8和gbk,默認編碼格式是UTF-8。
我們要根據導入文件本身的編碼格式進行設置,通過設置參數encoding來設置導入的編碼格式。
有的時候兩個文件看起來一樣,它們的文件名一樣,格式也一樣,但如果它們的編碼格式不一樣,也是不一樣的文件,比如當你把一個Excel文件另存為時會出現兩個選項,雖然都是.csv文件,但是這兩種格式代表兩種不同的文件。
# -*- coding:utf-8 -*-
import pandas as pd
# 指定編碼格式
df = pd.read_csv(r"~/Desktop/tt.csv",sep="|",nrows=1,encoding="utf-8")
print(df)
"""
name age gender
0 whw 19 male
"""
engine指定 *
當文件路徑或者文件名中包含中文時,如果還用上面的導入方式就會報錯。
這個時候我們就可以通過設置engine參數來消除這個錯誤。
這個錯誤產生的原因是當調用read_csv()方法時,默認使用C語言作為解析語言,我們只需要把默認值C更改為Python就可以了。
如果文件格式是CSV UTF-8(逗號分隔)(*.csv),那么編碼格式也需要跟着變為utf-8-sig,如果文件格式是CSV(逗號分隔)(*.csv)格式,對應的編碼格式則為gbk。
# -*- coding:utf-8 -*-
import pandas as pd
# 文件名包含中文
df = pd.read_csv(r"~/Desktop/王宏偉測試.csv",engine="python",encoding="utf-8-sig")
print(df)
"""
姓名 年齡
0 whw 12
1 www 22
2 wwwa 33
"""
4.1 導入外部數據(.txt文件)
(略 有需要再看) —— 現在數據基本不往txt里存了吧!
4.1 導入外部數據(.sql文件)
(略)—— 可以利用Python操作MySQL:SQLAlchemy、pymysql等~
4.2 新建數據
這里的新建數據主要指新建 DataFrame 數據,我們在第3章的時候講過,利用pd.DataFrame()方法進行新建。
4.3 熟悉數據
# -*- coding:utf-8 -*-
import pandas as pd
# 文件名包含中文
df = pd.read_csv(r"~/Desktop/王宏偉測試.csv",engine="python",encoding="utf-8-sig")
print(df)
"""
姓名 年齡
0 whw 12
1 www 22
2 wwwa 33
"""
# head()方法控制顯示的行數
print(df.head(2))
"""
姓名 年齡
0 whw 12
1 www 22
"""
# shape獲取數據表的大小
print(df.shape)
"""
(3, 2)
"""
# info()獲取數據類型
print(df.info())
"""
<class 'pandas.core.frame.DataFrame'>
RangeIndex: 3 entries, 0 to 2
Data columns (total 2 columns):
# Column Non-Null Count Dtype
--- ------ -------------- -----
0 姓名 3 non-null object
1 年齡 3 non-null int64
dtypes: int64(1), object(1)
memory usage: 176.0+ bytes
None
"""
# describe()獲取數值分布情況
print(df.describe())
"""
年齡
count 3.000000
mean 22.333333
std 10.503968
min 12.000000
25% 17.000000
50% 22.000000
75% 27.500000
max 33.000000
"""
第5章 數據預處理
從菜市場買來的菜,總有一些不太好的,所以把菜買回來以后要先做一遍預處理,把那些不太好的部分扔掉。現實中大部分的數據都類似於菜市場的菜品,拿到以后都要先做一次預處理。
常見的不規整數據主要有缺失數據、重復數據、異常數據幾種,在開始正式的數據分析之前,我們需要先把這些不太規整的數據處理掉。
5.1 缺失值處理
缺失值就是由某些原因導致部分數據為空,對於為空的這部分數據我們一般有兩種處理方式,一種是刪除,即把含有缺失值的數據刪除;另一種是填充,即把缺失的那部分數據用某個值代替。
缺失值查看
info()方法 ———— 上面的代碼有介紹!
對缺失值進行處理,首先要把缺失值找出來,也就是查看哪列有缺失值。
文件中的內容如下(年齡少了一個值):

使用info()方法獲取到的結果:

isnull()方法
# 使用isnull()判斷數據缺失情況
print(df.isnull())
"""
姓名 年齡
0 False False
1 False True # 這里的年齡是空的
2 False False
"""
缺失值刪除
缺失值分為兩種,一種是一行中某個字段是缺失值;另一種是一行中的字段全部為缺失值,即為一個空白行。
在Python中,我們利用的是dropna()方法,dropna()方法默認刪除含有缺失值的行,也就是只要某一行有缺失值就把這一行刪除。
# -*- coding:utf-8 -*-
import pandas as pd
# 文件名包含中文
df = pd.read_csv(r"~/Desktop/王宏偉測試.csv",engine="python",encoding="utf-8-sig")
print(df)
"""
姓名 年齡
0 whw 12
1 www NaN
2 wwwa 33
"""
# 刪除空行顯示
print(df.dropna())
"""
姓名 年齡
0 whw 12.0
2 wwwa 33.0
"""
如果想刪除空白行,只要給dropna()方法傳入一個參數how="all"即可,這樣就會只刪除那些全為空值的行,不全為空值的行就不會被刪除。
# -*- coding:utf-8 -*-
import pandas as pd
# 文件名包含中文
df = pd.read_csv(r"~/Desktop/王宏偉測試.csv",engine="python",encoding="utf-8-sig")
print(df)
"""
姓名 年齡
0 whw 12
1 www NaN
2 wwwa 33
"""
# 只刪除全是空白的行
print(df.dropna(how="all"))
"""
姓名 年齡
0 whw 12.0
1 www NaN
2 wwwa 33.0
"""
缺失值填充
上面介紹了缺失值的刪除,但是數據是寶貴的,一般情況下只要數據缺失比例不是過高(不大於30%),盡量別刪除,而是選擇填充。
在Python中,我們利用的fillna()方法對數據表中的所有缺失值進行填充,在fillna后面的括號中輸入要填充的值即可。
# -*- coding:utf-8 -*-
import pandas as pd
# 文件名包含中文
df = pd.read_csv(r"~/Desktop/王宏偉測試.csv",engine="python",encoding="utf-8-sig")
print(df)
"""
姓名 年齡
0 whw 12
1 www NaN
2 wwwa 33
"""
# 刪除空行顯示
print(df.fillna(18))
"""
姓名 年齡
0 whw 12.0
1 www 18.0
2 wwwa 33.0
"""
5.2 重復值處理
重復數據就是同樣的記錄有多條,對於這樣的數據我們一般做刪除處理。
在Python中我們利用drop_duplicates()方法,該方法默認對所有值進行重復值判斷,且默認保留第一個(行)值。
# -*- coding:utf-8 -*-
import pandas as pd
# 文件名包含中文
df = pd.read_csv(r"~/Desktop/王宏偉測試.csv",engine="python",encoding="utf-8-sig")
print(df)
"""
姓名 年齡
0 whw 12
1 www 19
2 wwwa 33
3 wwwa 33
4 www 19
"""
# 刪除重復值
print(df.drop_duplicates())
"""
姓名 年齡
0 whw 12
1 www 19
2 wwwa 33
"""
上面的代碼是針對所有字段進行的重復值判斷,我們同樣也可以只針對某一列或某幾列進行重復值刪除的判斷,只需要在drop_duplicates()方法中指明要判斷的列名即可。
# -*- coding:utf-8 -*-
# -*- coding:utf-8 -*-
import pandas as pd
# 文件名包含中文
df = pd.read_csv(r"~/Desktop/王宏偉測試.csv",engine="python",encoding="utf-8-sig")
print(df)
"""
姓名 年齡
0 whw 12
1 www 19
2 wwwa 33
3 wwwa 33
4 www 19
"""
# 刪除重復值 指定列名
print(df.drop_duplicates(subset=["姓名","年齡"]))
"""
姓名 年齡
0 whw 12
1 www 19
2 wwwa 33
"""
還可以自定義刪除重復項時保留哪個,默認保留第一個,也可以設置保留最后一個,或者全部不保留。通過傳入參數keep進行設置,參數keep默認值是first,即保留第一個值;也可以是last,保留最后一個值;還可以是False,即把重復值全部刪除。
# -*- coding:utf-8 -*-
import pandas as pd
# 文件名包含中文
df = pd.read_csv(r"~/Desktop/王宏偉測試.csv",engine="python",encoding="utf-8-sig")
print(df)
"""
姓名 年齡
0 whw 12
1 www 19
2 wwwa 33
3 wwwa 33
4 www 19
"""
# 刪除重復值 指定列名
print(df.drop_duplicates(subset=["姓名","年齡"],keep=False))
"""
姓名 年齡
0 whw 12
"""
5.3 異常值的檢測與處理
異常值就是相比正常數據而言過高或過低的數據,比如一個人的年齡是0歲或者300歲都算是一個異常值,因為這和實際情況差距過大。
異常值檢測
要處理異常值首先要檢測,也就是發現異常值,發現異常值的方式主要有以下三種。
- 根據業務經驗划定不同指標的正常范圍,超過該范圍的值算作異常值。
- 通過繪制箱形圖,把大於(小於)箱形圖上邊緣(下邊緣)的點稱為異常值。
- 如果數據服從正態分布,則可以利用3σ 原則;如果一個數值與平均值之間的偏差超過3倍標准差,那么我們就認為這個值是異常值。
箱形圖如下圖所示,關於箱形圖的繪制方法我們會在第13章介紹。

下圖為正態分布圖,我們把大於μ+3σ的值稱為異常值。

異常值處理
對於異常值一般有以下幾種處理方式。
- 最常用的處理方式就是刪除。
- 把異常值當作缺失值來填充。
- 把異常值當作特殊情況,研究異常值出現的原因。
在Python中,刪除異常值用到的方法和Excel中的方法原理類似,Python中是通過過濾的方法對異常值進行刪除。比如 df 表中有年齡這個指標,要把年齡大於200的值刪掉,你可以通過篩選把年齡不大於200的篩出來,篩出來的部分就是刪除大於200的值以后的新表。
對異常值進行填充,就是對異常值進行替換,利用replace()方法可以對特定的值進行替換。
關於數據篩選和數據替換會在接下來的章節介紹。
5.4 數據類型轉換
數據類型
Pandas不像Excel分得那么詳細,它主要有6種數據類型,如下表所示。

在 Python 中,不僅可以用 info()方法獲取每一列的數據類型,還可以通過 dtype方法來獲取某一列的數據類型。
# -*- coding:utf-8 -*-
import pandas as pd
# 文件名包含中文
df = pd.read_csv(r"~/Desktop/王宏偉測試.csv",engine="python",encoding="utf-8-sig")
print(df)
"""
姓名 年齡
0 whw 12
1 www 19
2 wwwa 33
3 wwwa 33
4 www 19
"""
# dtype方法獲取某一列的數據類型
print(df["姓名"].dtype) # object
print(df["年齡"].dtype) # int64
類型轉換
在Python中,我們利用astype()方法對數據類型進行轉換,astype后面的括號里指明要轉換的目標類型即可。
# -*- coding:utf-8 -*-
import pandas as pd
# 文件名包含中文
df = pd.read_csv(r"~/Desktop/王宏偉測試.csv",engine="python",encoding="utf-8-sig")
print(df)
"""
姓名 年齡
0 whw 12
1 www 19
2 wwwa 33
3 wwwa 33
4 www 19
"""
# astype方法對數據類型進行轉換
# 注意得獲取返回值!!不會在源數據上修改!!!
ret = df["年齡"].astype("float64")
print(ret)
"""
0 12.0
1 19.0
2 33.0
3 33.0
4 19.0
Name: 年齡, dtype: float64
"""
5.5 索引設置
索引是查找數據的依據,設置索引的目的是便於我們查找數據。舉個例子,你逛超市買了很多食材,回到家以后要把它們放在冰箱里,放的過程其實就是一個建立索引的過程,比如蔬菜放在冷藏室,肉類放在冷凍室,這樣在找的時候就能很快找到。
為無索引表添加索引
在Python中,如果表沒有索引,會默認用從0開始的自然數做索引,比如下面這樣:
# -*- coding:utf-8 -*-
import pandas as pd
df1 = pd.DataFrame([["aa","A"],["bb","B"],["cc","C"]])
print(df1)
"""
0 1
0 aa A
1 bb B
2 cc C
"""
通過給表df的columns參數傳入列索引值,index參數傳入行索引值達到為無索引表添加索引的目的,具體實現如下:
# -*- coding:utf-8 -*-
import pandas as pd
df1 = pd.DataFrame([["aa","A"],["bb","B"],["cc","C"]])
print(df1)
"""
0 1
0 aa A
1 bb B
2 cc C
"""
# 添加列索引值
df1.columns = ["小寫","大寫"]
print(df1)
"""
小寫 大寫
0 aa A
1 bb B
2 cc C
"""
# 添加行索引值
df1.index = [1,2,3]
print(df1)
"""
小寫 大寫
1 aa A
2 bb B
3 cc C
"""
重新設置索引
重新設置索引,一般指行索引的設置。有的表雖然有索引,但不是我們想要的索引,比如現在有一個表是把序號作為行索引,而我們想要把訂單編號作為行索引,該怎么實現呢?
在Excel中重新設置行索引比較簡單,你想讓哪一列做行索引,直接把這一列拖到第一列的位置即可。
在Python中可以利用set_index()方法重新設置索引列,在set_index()里指明要用作行索引的列的名稱即可。
# -*- coding:utf-8 -*-
import pandas as pd
df1 = pd.DataFrame([["aa","A"],["bb","B"],["cc","C"]])
print(df1)
"""
0 1
0 aa A
1 bb B
2 cc C
"""
# 添加列索引值
df1.columns = ["小寫","大寫"]
print(df1)
"""
小寫 大寫
0 aa A
1 bb B
2 cc C
"""
# 添加行索引值
df1.index = [1,2,3]
print(df1)
"""
小寫 大寫
1 aa A
2 bb B
3 cc C
"""
# 重新設置索引 ———— 注意 獲取的是返回值!!!
ret = df1.set_index(["大寫"])
print(ret)
"""
小寫
大寫
A aa
B bb
C cc
"""
在重新設置索引時,還可以給 set_index()方法傳入兩個或多個列名,我們把這種一個表中用多列來做索引的方式稱為層次化索引,層次化索引一般用在某一列中含有多個重復值的情況下。層次化索引的例子,如下所示,其中 a、b、c、d 分別有多個重復值。

重命名索引
在Python中重命名索引,我們利用的是rename()方法,在rename后的括號里指明要修改的行索引及列索引名。
# -*- coding:utf-8 -*-
import pandas as pd
df1 = pd.DataFrame([["aa","A"],["bb","B"],["cc","C"]])
print(df1)
"""
0 1
0 aa A
1 bb B
2 cc C
"""
# 添加列索引值
df1.columns = ["小寫","大寫"]
print(df1)
"""
小寫 大寫
0 aa A
1 bb B
2 cc C
"""
# 添加行索引值
df1.index = [1,2,3]
print(df1)
"""
小寫 大寫
1 aa A
2 bb B
3 cc C
"""
# 重命名列索引 注意獲取的是返回值!!!
ret1 = df1.rename(columns={"小寫":"lower","大寫":"upper"})
print(ret1)
"""
lower upper
1 aa A
2 bb B
3 cc C
"""
# 重命名行索引 注意獲取的是返回值!!!
ret2 = df1.rename(index={1:"一",2:"二",3:"三"})
print(ret2)
"""
小寫 大寫
一 aa A
二 bb B
三 cc C
"""
重置索引 ***
重置索引主要用在層次化索引表中,重置索引是將索引列當作一個columns進行返回。
在下圖左側的表中,Z1、Z2是一個層次化索引,經過重置索引以后,Z1、Z2這兩個索引以columns的形式返回,變為常規的兩列。

在Excel中,我們要進行這種轉換,直接通過復制、粘貼、刪除等功能就可以實現,比較簡單。我們主要講一下在Python中怎么實現。
在Python利用的是reset_index()方法,reset_index()方法常用於數據分組、數據透視表中。
reset_index()方法常用的參數如下:
reset_index(level=None, drop=False, inplace=False)
level參數用來指定要將層次化索引的第幾級別轉化為columns,第一個索引為0級,第二個索引為1級,默認為全部索引,即默認把索引全部轉化為columns。
drop參數用來指定是否將原索引刪掉,即不作為一個新的columns,默認為False,即不刪除原索引。
inplace參數用來指定是否修改原數據表。

第6章 數據選擇
之前是把所有的菜品都洗好並放在不同的容器里。現在要進行切配了,需要把這些菜品挑選出來,比如做一盤涼拌黃瓜,需要先把黃瓜找出來;要做一盤可樂雞翅,需要先把雞翅找出來。
數據分析也是同樣的道理,你要分析什么,首先要把對應的數據篩選出來。
常規的數據選擇主要有列選擇、行選擇、行列同時選擇三種方式。
6.1 列選擇 ***
選擇某1列/某幾列
位置索引 —— 通過傳入具體位置來選擇數據的方式。
方法1
在Python中我們要想獲取某列只需要在表df后面的方括號中指明要選擇的列名即可。如果是一列,則只需要傳入一個列名;如果是同時選擇多列,則傳入多個列名即可,多個列名用一個list存起來。
# -*- coding:utf-8 -*-
import pandas as pd
df = pd.read_csv(r"~/Desktop/王宏偉測試.csv")
print(df)
"""
姓名 年齡 性別
0 whw 12 male
1 www 19 male
2 wwwa 33 female
3 whh 23 female
"""
# 選擇某一列
ret1 = df["姓名"]
print(ret1)
"""
0 whw
1 www
2 wwwa
3 whh
Name: 姓名, dtype: object
"""
# 選擇某幾列
ret2 = df[["姓名","性別"]]
print(ret2)
"""
姓名 性別
0 whw male
1 www male
2 wwwa female
3 whh female
"""
方法2
除了傳入具體的列名,我們還可以傳入具體列的位置,即第幾列,對數據進行選取,通過傳入位置來獲取數據時需要用到iloc方法。
# -*- coding:utf-8 -*-
import pandas as pd
df = pd.read_csv(r"~/Desktop/王宏偉測試.csv")
print(df)
"""
姓名 年齡 性別
0 whw 12 male
1 www 19 male
2 wwwa 33 female
3 whh 23 female
"""
# 選取第1列與第3列的所有行的數據
ret = df.iloc[:,[0,2]]
print(ret)
""" 姓名 性別
0 whw male
1 www male
2 wwwa female
3 whh female
"""
在上面的代碼中,iloc 后的方括號中逗號之前的部分表示要獲取的行的位置,只輸入一個冒號,不輸入任何數值表示獲取所有的行;逗號之后的方括號表示要獲取的列的位置,列的位置同樣是也是從0開始計數。
選擇連續的某幾列
在Python中可以通過前面介紹的普通索引和位置索引獲取某一列或多列的數據。當你要獲取的是連續的某幾列,用普通索引和位置索引也是可以做到的,但是因為你要獲取的列是連續的,所以只要傳入這些連續列的位置區間即可,同樣需要用到iloc方法。
# -*- coding:utf-8 -*-
import pandas as pd
df = pd.read_csv(r"~/Desktop/王宏偉測試.csv")
print(df)
"""
姓名 年齡 性別
0 whw 12 male
1 www 19 male
2 wwwa 33 female
3 whh 23 female
"""
# 選取第1列與第3列的所有行的數據
ret = df.iloc[:,[0,2]]
print(ret)
""" 姓名 性別
0 whw male
1 www male
2 wwwa female
3 whh female
"""
在上面的代碼中,iloc 后的方括號中逗號之前的表示選擇的行,當只傳入一個冒號時,表示選擇所有行;逗號后面表示要選擇列的位置區間,0:3表示選擇第1列到第4列之間的值(包含第1列但不包含第4列),我們把這種通過傳入一個位置區間來獲取數據的方式稱為切片索引。
6.2 行選擇 ***
在Python中,獲取行的方式主要有兩種:
一種是普通索引,即傳入具體行索引的名稱,需要用到loc方法;
另一種是位置索引,即傳入具體的行數,需要用到iloc方法。
loc方法
# -*- coding:utf-8 -*-
import pandas as pd
df = pd.read_csv(r"~/Desktop/王宏偉測試.csv")
print(df)
"""
姓名 年齡 性別
0 whw 12 male
1 www 19 male
2 wwwa 33 female
3 whh 23 female
"""
# 選擇一行
print(df.loc[0])
"""
姓名 whw
年齡 12
性別 male
Name: 0, dtype: object
"""
### 重命名行索引后再試試
ret = df.rename(index={0:"一",1:"二",2:"三",3:"四"})
print(ret)
"""
姓名 年齡 性別
一 whw 12 male
二 www 19 male
三 wwwa 33 female
四 whh 23 female
"""
# 選擇一行
print(ret.loc["一"])
"""
姓名 whw
年齡 12
性別 male
Name: 一, dtype: object
"""
# 選擇第一行與第三行
print(ret.loc[["一","三"]])
"""
姓名 年齡 性別
一 whw 12 male
三 wwwa 33 female
"""
iloc方法
# -*- coding:utf-8 -*-
import pandas as pd
df = pd.read_csv(r"~/Desktop/王宏偉測試.csv")
print(df)
"""
姓名 年齡 性別
0 whw 12 male
1 www 19 male
2 wwwa 33 female
3 whh 23 female
"""
# 選擇一行
print(df.iloc[0])
"""
姓名 whw
年齡 12
性別 male
Name: 0, dtype: object
"""
# 選擇第一行與第二行
print(df.iloc[[0,1]])
"""
姓名 年齡 性別
0 whw 12 male
1 www 19 male
"""
選擇連續的幾行
在Python中,選擇連續的某幾行時,你同樣可以把要選擇的每一個行索引名字或者行索引的位置輸進去。很顯然這是沒有必要的,只要把連續行的位置用一個區間表示,然后傳給iloc即可。
# -*- coding:utf-8 -*-
import pandas as pd
df = pd.read_csv(r"~/Desktop/王宏偉測試.csv")
print(df)
"""
姓名 年齡 性別
0 whw 12 male
1 www 19 male
2 wwwa 33 female
3 whh 23 female
"""
# 選擇第一行與到第三行 —— 左閉右開區間
print(df.iloc[0:3])
"""
姓名 年齡 性別
0 whw 12 male
1 www 19 male
2 wwwa 33 female
"""
選擇滿足條件的行
比如年齡這一列,需要把非異常值(大於200的屬於異常值),即小於200歲的年齡篩選出來,該怎么實現呢?
在Excel中我們直接使用篩選功能,將滿足條件的值篩選出來,篩選方法如下圖所示。

Python實現
在Python中,我們直接在表名后面指明哪列要滿足什么條件,就可以把滿足條件的數據篩選出來。
# -*- coding:utf-8 -*-
import pandas as pd
df = pd.read_csv(r"~/Desktop/王宏偉測試.csv")
print(df)
"""
姓名 年齡 性別
0 whw 12 male
1 www 19 male
2 wwwa 33 female
3 whh 23 female
"""
# 篩選出性別為male的
ret = df[df["性別"]=="male"]
print(ret)
"""
姓名 年齡 性別
0 whw 12 male
1 www 19 male
"""
我們把上面這種通過傳入一個判斷條件來選擇數據的方式稱為布爾索引。
傳入的條件還可以是多個,如下為選擇的年齡小於200且唯一識別碼小於102的數據。
# -*- coding:utf-8 -*-
import pandas as pd
df = pd.read_csv(r"~/Desktop/王宏偉測試.csv")
print(df)
"""
姓名 年齡 性別
0 whw 12 male
1 www 19 male
2 wwwa 33 female
3 whh 23 female
"""
### 篩選出性別為male 並且年齡大於15歲的
## 寫法1
# 兩個條件
condition1 = df["性別"]=="male"
condition2 = df["年齡"]>15
# 條件
condition = condition1 & condition2
# 結果
ret = df[condition]
print(ret)
"""
姓名 年齡 性別
0 whw 12 male
1 www 19 male
"""
## 寫法2 —— 結合一下即可
ret2 = df[(df["性別"]=="male") & (df["年齡"]>15)]
print(ret2)
"""
姓名 年齡 性別
1 www 19 male
"""
6.3 行列同時選擇 ***
上面的數據選擇都是針對單一的行或列進行選擇,實際業務中我們也會用到行、列同時選擇,所謂的行、列同時選擇就是選擇出行和列的相交部分。
例如,我們要選擇第二、三行和第二、三列相交部分的數據,下圖中的陰影部分就是最終的選擇結果。

“普通索引+普通索引”選擇指定的行和列
普通索引+普通索引就是通過同時傳入行和列的索引名稱進行數據選擇,需要用到loc方法。
# -*- coding:utf-8 -*-
import pandas as pd
df = pd.read_csv(r"~/Desktop/王宏偉測試.csv")
print(df)
"""
姓名 年齡 性別
0 whw 12 male
1 www 19 male
2 wwwa 33 female
3 whh 23 female
"""
# 利用loc方法傳入行列名稱
ret = df.loc[[0,1],["姓名","性別"]]
print(ret)
"""
姓名 性別
0 whw male
1 www male
"""
loc方法中的第一對方括號表示行索引的選擇,傳入行索引名稱;loc方法中的第二對方括號表示列索引的選擇,傳入列索引名稱。
"位置索引+位置索引"選擇指定的行與列
位置索引+位置索引是通過同時傳入行、列索引的位置來獲取數據,需要用到iloc方法。
# -*- coding:utf-8 -*-
import pandas as pd
df = pd.read_csv(r"~/Desktop/王宏偉測試.csv")
print(df)
"""
姓名 年齡 性別
0 whw 12 male
1 www 19 male
2 wwwa 33 female
3 whh 23 female
"""
# 利用iloc方法傳入行列位置
ret = df.iloc[[2,3],[0,2]]
print(ret)
"""
姓名 性別
2 wwwa female
3 whh female
"""
在iloc方法中的第一對方括號表示行索引的選擇,傳入要選擇行索引的位置;第二對方括號表示列索引的選擇,傳入要選擇列索引的位置。行和列索引的位置都是從0開始計數。
"布爾索引+普通索引"選擇指定的行和列
布爾索引+普通索引是先對表進行布爾索引選擇行,然后通過普通索引選擇列。
# -*- coding:utf-8 -*-
import pandas as pd
df = pd.read_csv(r"~/Desktop/王宏偉測試.csv")
print(df)
"""
姓名 年齡 性別
0 whw 12 male
1 www 19 male
2 wwwa 33 female
3 whh 23 female
"""
# 先進行布爾索引選擇行 然后通過普通索引選擇列
ret = df[df["年齡"]<20][["姓名","年齡","性別"]]
print(ret)
"""
姓名 年齡 性別
0 whw 12 male
1 www 19 male
"""
"切片索引+切片索引"選擇指定的行和列
切片索引+切片索引是通過同時傳入行、列索引的位置區間進行數據選擇。
# -*- coding:utf-8 -*-
import pandas as pd
df = pd.read_csv(r"~/Desktop/王宏偉測試.csv")
print(df)
"""
姓名 年齡 性別
0 whw 12 male
1 www 19 male
2 wwwa 33 female
3 whh 23 female
"""
# 左閉右開區間
ret = df.iloc[0:2,0:2]
print(ret)
"""
姓名 年齡
0 whw 12
1 www 19
"""
"切片索引+普通索引"選擇指定的行和列(ix方法已移除!)
前面我們說過,如果是普通索引,就直接傳入行或列名,用loc方法即可;如果是切片索引,也就是傳入行或列的位置區間,要用 iloc 方法。如果是切片索引+普通索引,也就是行(列)用切片索引,列(行)用普通索引,這種交叉索引要用ix方法。
# -*- coding:utf-8 -*-
import pandas as pd
df = pd.read_csv(r"~/Desktop/王宏偉測試.csv")
print(df)
"""
姓名 年齡 性別
0 whw 12 male
1 www 19 male
2 wwwa 33 female
3 whh 23 female
"""
# 注意下面的代碼會報錯!!!
ret = df.ix[0:2,["姓名","性別"]]
print(ret)
"""
AttributeError: 'DataFrame' object has no attribute 'ix'
"""
注意:在pandas的1.0.0版本開始,移除了Series.ix and DataFrame.ix 方法!!!
7--15章 都是pandas/matplotlib/numpy的操作
7--15章內容與我之前做的筆記重復了,詳情請看之前這篇筆記:
