一文看懂怎么用Python做數(shù)據(jù)分析
常遇到兩類朋友。一類是會(huì)爬蟲但不知道如何進(jìn)一步做數(shù)據(jù)分析的,一類是平常用 Excel 做分析但不太會(huì)用 Python 分析的。如果和你很像,那下面這篇系統(tǒng)長文會(huì)很適合你,建議先收藏。
Excel 是數(shù)據(jù)分析中最常用的工具,本文通過 Python 與 excel 的功能對(duì)比介紹如何使用 Python 通過函數(shù)式編程完成 excel 中的數(shù)據(jù)處理及分析工作。從 1787 頁的 pandas 官網(wǎng)文檔中總結(jié)出最常用的 36 個(gè)函數(shù),通過這些函數(shù)介紹如何通過 Python 完成數(shù)據(jù)生成和導(dǎo)入、數(shù)據(jù)清洗、預(yù)處理、數(shù)據(jù)分類、數(shù)據(jù)篩選、分類 匯總、透視等最常見的操作。
文章內(nèi)容共分為 9 個(gè)部分目錄如下:

01 生成數(shù)據(jù)表
***部分是生成數(shù)據(jù)表,常見的生成方法有兩種,***種是導(dǎo)入外部數(shù)據(jù),第二種是直接寫入數(shù)據(jù)。 Excel 中的文件菜單中提供了獲取外部數(shù)據(jù)的功能,支持?jǐn)?shù)據(jù)庫和文本文件和頁面的多種數(shù)據(jù)源導(dǎo)入。

python 支持從多種類型的數(shù)據(jù)導(dǎo)入。在開始使用 python 進(jìn)行數(shù)據(jù)導(dǎo)入前需要先導(dǎo)入 pandas 庫,為了方便起見,我們也同時(shí)導(dǎo)入 numpy 庫。
- import numpy as np
- import pandas as pd
導(dǎo)入數(shù)據(jù)表
下面分別是從 excel 和 csv 格式文件導(dǎo)入數(shù)據(jù)并創(chuàng)建數(shù)據(jù)表的方法。代碼是最簡(jiǎn)模式,里面有很多可選參數(shù)設(shè)置,例如列名稱,索引列,數(shù)據(jù)格式等等。感興趣的朋友可以參考 pandas 的
官方文檔。
- df=pd.DataFrame(pd.read_csv('name.csv',header=1))
- df=pd.DataFrame(pd.read_excel('name.xlsx'))
創(chuàng)建數(shù)據(jù)表
另一種方法是通過直接寫入數(shù)據(jù)來生成數(shù)據(jù)表,excel 中直接在單元格中輸入數(shù)據(jù)就可以,python 中通過下面的代碼來實(shí)現(xiàn)。生成數(shù)據(jù)表的函數(shù)是 pandas 庫中的 DateFrame 函數(shù),數(shù)據(jù)表一共有 6 行數(shù)據(jù),每行有 6 個(gè)字段。在數(shù)據(jù)中我們特意設(shè)置了一些 NA 值和有問題的字段,例如包含空格等。后面將在數(shù)據(jù)清洗步驟進(jìn)行處理。后面我們將統(tǒng)一以 DataFrame 的簡(jiǎn)稱 df 來命名數(shù)據(jù)表。
- df = pd.DataFrame({"id":[1001,1002,1003,1004,1005,1006],
- "date":pd.date_range('20130102', periods=6),
- "city":['Beijing ', 'SH', ' guangzhou ', 'Shenzhen', 'shanghai', 'BEIJING '],
- "age":[23,44,54,32,34,32],
- "category":['100-A','100-B','110-A','110-C','210-A','130-F'],
- "price":[1200,np.nan,2133,5433,np.nan,4432]},
- columns =['id','date','city','category','age','price'])
這是剛剛創(chuàng)建的數(shù)據(jù)表,我們沒有設(shè)置索引列,price 字段中包含有 NA 值,city 字段中還包含了一些臟數(shù)據(jù)。

02 數(shù)據(jù)表檢查
第二部分是對(duì)數(shù)據(jù)表進(jìn)行檢查,python 中處理的數(shù)據(jù)量通常會(huì)比較大,比如我們之前的文章中介紹的紐約出租車數(shù)據(jù)和 Citibike 的騎行數(shù)據(jù),數(shù)據(jù)量都在***,我們無法一目了然的 了解數(shù)據(jù)表的整體情況,必須要通過一些方法來獲得數(shù)據(jù)表的關(guān)鍵信息。數(shù)據(jù)表檢查的另一個(gè)目的是了解數(shù)據(jù)的概況,例如整個(gè)數(shù)據(jù)表的大小,所占空間,數(shù)據(jù)格式,是否有空值和重復(fù)項(xiàng)和具體的數(shù)據(jù)內(nèi)容。為后面的清洗和預(yù)處理做好準(zhǔn)備。
數(shù)據(jù)維度(行列)
Excel 中可以通過 CTRL+向下的光標(biāo)鍵,和 CTRL+向右的光標(biāo)鍵來查看行號(hào)和列號(hào)。Python 中使用 shape 函數(shù)來查看數(shù)據(jù)表的維度,也就是行數(shù)和列數(shù),函數(shù)返回的結(jié)果(6,6)表示數(shù)據(jù)表有 6 行,6 列。下面是具體的代碼。
- #查看數(shù)據(jù)表的維度
- df.shape
- (6, 6)
數(shù)據(jù)表信息
使用 info 函數(shù)查看數(shù)據(jù)表的整體信息,這里返回的信息比較多,包括數(shù)據(jù)維度,列名稱,數(shù)據(jù)格式和所占空間等信息。
- #數(shù)據(jù)表信息
- df.info()
- <class 'pandas.core.frame.DataFrame'>
- RangeIndex: 6 entries, 0 to 5
- Data columns (total 6 columns):
- id 6 non-null int64
- date 6 non-null datetime64[ns]
- city 6 non-null object
- category 6 non-null object
- age 6 non-null int64
- price 4 non-null float64
- dtypes: datetime64[ns](1), float64(1), int64(2), object(2)
- memory usage: 368.0+ bytes
查看數(shù)據(jù)格式
Excel 中通過選中單元格并查看開始菜單中的數(shù)值類型來判斷數(shù)據(jù)的格式。Python 中使用 dtypes 函數(shù)來返回?cái)?shù)據(jù)格式。

Dtypes 是一個(gè)查看數(shù)據(jù)格式的函數(shù),可以一次性查看數(shù)據(jù)表中所有數(shù)據(jù)的格式,也可以指定一列來單獨(dú)查看。
- #查看數(shù)據(jù)表各列格式
- df.dtypes
- id int64
- date datetime64[ns]
- city object
- category object
- age int64
- price float64
- dtype: object
- #查看單列格式
- df['B'].dtype
- dtype('int64')
查看空值
Excel 中查看空值的方法是使用“定位條件”功能對(duì)數(shù)據(jù)表中的空值進(jìn)行定位。“定位條件”在“開始”目錄下的“查找和選擇”目錄中。

Isnull 是 Python 中檢驗(yàn)空值的函數(shù),返回的結(jié)果是邏輯值,包含空值返回 True,不包含則返回 False??梢詫?duì)整個(gè)數(shù)據(jù)表進(jìn)行檢查,也可以單獨(dú)對(duì)某一列進(jìn)行空值檢查。
- #檢查數(shù)據(jù)空值
- df.isnull()

- #檢查特定列空值
- df['price'].isnull()
- 0 False
- 1 True
- 2 False
- 3 False
- 4 True
- 5 False
- Name: price, dtype: bool
查看唯一值
Excel 中查看唯一值的方法是使用“條件格式”對(duì)唯一值進(jìn)行顏色標(biāo)記。Python 中使用 unique 函數(shù)查看唯一值。

Unique 是查看唯一值的函數(shù),只能對(duì)數(shù)據(jù)表中的特定列進(jìn)行檢查。下面是代碼,返回的結(jié)果是該列中的唯一值。類似與 Excel 中刪除重復(fù)項(xiàng)后的結(jié)果。
- #查看city列中的唯一值
- df['city'].unique()
- array(['Beijing ', 'SH', ' guangzhou ', 'Shenzhen', 'shanghai', 'BEIJING '], dtype=object)
查看數(shù)據(jù)表數(shù)值
Python 中的 Values 函數(shù)用來查看數(shù)據(jù)表中的數(shù)值。以數(shù)組的形式返回,不包含表頭信息。
- #查看數(shù)據(jù)表的值
- df.values
- array([[1001, Timestamp('2013-01-02 00:00:00'), 'Beijing ', '100-A', 23,
- 1200.0],
- [1002, Timestamp('2013-01-03 00:00:00'), 'SH', '100-B', 44, nan],
- [1003, Timestamp('2013-01-04 00:00:00'), ' guangzhou ', '110-A', 54,
- 2133.0],
- [1004, Timestamp('2013-01-05 00:00:00'), 'Shenzhen', '110-C', 32,
- 5433.0],
- [1005, Timestamp('2013-01-06 00:00:00'), 'shanghai', '210-A', 34,
- nan],
- [1006, Timestamp('2013-01-07 00:00:00'), 'BEIJING ', '130-F', 32,
- 4432.0]], dtype=object)
查看列名稱
Colums 函數(shù)用來單獨(dú)查看數(shù)據(jù)表中的列名稱。
- #查看列名稱
- df.columns
- Index(['id', 'date', 'city', 'category', 'age', 'price'], dtype='object')
查看前 10 行數(shù)據(jù)
Head 函數(shù)用來查看數(shù)據(jù)表中的前 N 行數(shù)據(jù),默認(rèn) head()顯示前 10 行數(shù)據(jù),可以自己設(shè)置參數(shù)值來確定查看的行數(shù)。下面的代碼中設(shè)置查看前 3 行的數(shù)據(jù)。
- #查看前3行數(shù)據(jù)
- df.head(3)

查看后 10 行數(shù)據(jù)
Tail 行數(shù)與 head 函數(shù)相反,用來查看數(shù)據(jù)表中后 N 行的數(shù)據(jù),默認(rèn) tail()顯示后 10 行數(shù)據(jù),可以自己設(shè)置參數(shù)值來確定查看的行數(shù)。下面的代碼中設(shè)置查看后 3 行的數(shù)據(jù)。
- #查看***3行
- df.tail(3)

03 數(shù)據(jù)表清洗
第三部分是對(duì)數(shù)據(jù)表中的問題進(jìn)行清洗。主要內(nèi)容包括對(duì)空值,大小寫問題,數(shù)據(jù)格式和重復(fù)值的處理。這里不包含對(duì)數(shù)據(jù)間的邏輯驗(yàn)證。
處理空值(刪除或填充)
我們?cè)趧?chuàng)建數(shù)據(jù)表的時(shí)候在 price 字段中故意設(shè)置了幾個(gè) NA 值。對(duì)于空值的處理方式有很多種,可以直接刪除包含空值的數(shù)據(jù),也可以對(duì)空值進(jìn)行填充,比如用 0 填充或者用均值填充。還可以根據(jù)不同字段的邏輯對(duì)空值進(jìn)行推算。
Excel 中可以通過“查找和替換”功能對(duì)空值進(jìn)行處理,將空值統(tǒng)一替換為 0 或均值。也可以通過“定位”空值來實(shí)現(xiàn)。

Python 中處理空值的方法比較靈活,可以使用 Dropna 函數(shù)用來刪除數(shù)據(jù)表中包含空值的數(shù)據(jù),也可以使用 fillna 函數(shù)對(duì)空值進(jìn)行填充。下面的代碼和結(jié)果中可以看到使用 dropna 函數(shù)后,包含 NA 值的兩個(gè)字段已經(jīng)不見了。返回的是一個(gè)不包含空值的數(shù)據(jù)表。
- #刪除數(shù)據(jù)表中含有空值的行
- df.dropna(how='any')

除此之外也可以使用數(shù)字對(duì)空值進(jìn)行填充,下面的代碼使用 fillna 函數(shù)對(duì)空值字段填充數(shù)字 0。
- #使用數(shù)字0填充數(shù)據(jù)表中空值
- df.fillna(value=0)
我們選擇填充的方式來處理空值,使用 price 列的均值來填充 NA 字段,同樣使用 fillna 函數(shù),在要填充的數(shù)值中使用 mean 函數(shù)先計(jì)算 price 列當(dāng)前的均值,然后使用這個(gè)均值對(duì) NA 進(jìn)行填充??梢钥吹絻蓚€(gè)空值字段顯示為 3299.5。
- #使用price均值對(duì)NA進(jìn)行填充
- df['price'].fillna(df['price'].mean())
- 0 1200.0
- 1 3299.5
- 2 2133.0
- 3 5433.0
- 4 3299.5
- 5 4432.0
- Name: price, dtype: float64

清理空格
除了空值,字符中的空格也是數(shù)據(jù)清洗中一個(gè)常見的問題,下面是清除字符中空格的代碼。
- #清除city字段中的字符空格
- df['city']=df['city'].map(str.strip)
大小寫轉(zhuǎn)換
在英文字段中,字母的大小寫不統(tǒng)一也是一個(gè)常見的問題。Excel 中有 UPPER,LOWER 等函數(shù),python 中也有同名函數(shù)用來解決大小寫的問題。在數(shù)據(jù)表的 city 列中就存在這樣的問題。我們將 city 列的所有字母轉(zhuǎn)換為小寫。下面是具體的代碼和結(jié)果。
- #city列大小寫轉(zhuǎn)換
- df['city']=df['city'].str.lower()

更改數(shù)據(jù)格式
Excel 中通過“設(shè)置單元格格式”功能可以修改數(shù)據(jù)格式。Python 中通過 astype 函數(shù)用來修改數(shù)據(jù)格式。

Python 中 dtype 是查看數(shù)據(jù)格式的函數(shù),與之對(duì)應(yīng)的是 astype 函數(shù),用來更改數(shù)據(jù)格式。下面的代碼中將 price 字段的值修改為 int 格式。
- #更改數(shù)據(jù)格式
- df['price'].astype('int')
- 0 1200
- 1 3299
- 2 2133
- 3 5433
- 4 3299
- 5 4432
- Name: price, dtype: int32
更改列名稱
Rename 是更改列名稱的函數(shù),我們將來數(shù)據(jù)表中的 category 列更改為 category-size。下面是具體的代碼和更改后的結(jié)果。
- #更改列名稱
- df.rename(columns={'category': 'category-size'})

刪除重復(fù)值
很多數(shù)據(jù)表中還包含重復(fù)值的問題,Excel 的數(shù)據(jù)目錄下有“刪除重復(fù)項(xiàng)”的功能,可以用來刪除數(shù)據(jù)表中的重復(fù)值。默認(rèn) Excel 會(huì)保留***出現(xiàn)的數(shù)據(jù),刪除后面重復(fù)出現(xiàn)的數(shù)據(jù)。

Python 中使用 drop_duplicates 函數(shù)刪除重復(fù)值。我們以數(shù)據(jù)表中的 city 列為例,city 字段中存在重復(fù)值。默認(rèn)情況下 drop_duplicates()將刪除后出現(xiàn)的重復(fù)值(與 excel 邏輯一致)。增加 keep=’last’參數(shù)后將刪除***出現(xiàn)的重復(fù)值,保留***的值。下面是具體的代碼和比較結(jié)果。
原始的 city 列中 beijing 存在重復(fù),分別在***位和***一位。
- df['city']
- 0 beijing
- 1 sh
- 2 guangzhou
- 3 shenzhen
- 4 shanghai
- 5 beijing
- Name: city, dtype: object
使用默認(rèn)的 drop_duplicates()函數(shù)刪除重復(fù)值,從結(jié)果中可以看到***位的 beijing 被保留,***出現(xiàn)的 beijing 被刪除。
- #刪除后出現(xiàn)的重復(fù)值
- df['city'].drop_duplicates()
- 0 beijing
- 1 sh
- 2 guangzhou
- 3 shenzhen
- 4 shanghai
- Name: city, dtype: object
設(shè)置 keep=’last‘’參數(shù)后,與之前刪除重復(fù)值的結(jié)果相反,***位出現(xiàn)的 beijing 被刪除,保留了***一位出現(xiàn)的 beijing。
- #刪除先出現(xiàn)的重復(fù)值
- df['city'].drop_duplicates(keep='last')
- 1 sh
- 2 guangzhou
- 3 shenzhen
- 4 shanghai
- 5 beijing
- Name: city, dtype: objec
數(shù)值修改及替換
數(shù)據(jù)清洗中***一個(gè)問題是數(shù)值修改或替換,Excel 中使用“查找和替換”功能就可以實(shí)現(xiàn)數(shù)值的替換。

Python 中使用 replace 函數(shù)實(shí)現(xiàn)數(shù)據(jù)替換。數(shù)據(jù)表中 city 字段上海存在兩種寫法,分別為 shanghai 和 SH。我們使用 replace 函數(shù)對(duì) SH 進(jìn)行替換。
- #數(shù)據(jù)替換
- df['city'].replace('sh', 'shanghai')
- 0 beijing
- 1 shanghai
- 2 guangzhou
- 3 shenzhen
- 4 shanghai
- 5 beijing
- Name: city, dtype: object
本篇文章這是系列的第二篇,介紹第 4-6 部分的內(nèi)容,數(shù)據(jù)表生成,數(shù)據(jù)表查看,和數(shù)據(jù)清洗。

04 數(shù)據(jù)預(yù)處理
第四部分是數(shù)據(jù)的預(yù)處理,對(duì)清洗完的數(shù)據(jù)進(jìn)行整理以便后期的統(tǒng)計(jì)和分析工作。主要包括數(shù)據(jù)表的合并,排序,數(shù)值分列,數(shù)據(jù)分
組及標(biāo)記等工作。
數(shù)據(jù)表合并
首先是對(duì)不同的數(shù)據(jù)表進(jìn)行合并,我們這里創(chuàng)建一個(gè)新的數(shù)據(jù)表 df1,并將 df 和 df1 兩個(gè)數(shù)據(jù)表進(jìn)行合并。在 Excel 中沒有直接完成數(shù)據(jù)表合并的功能,可以通過 VLOOKUP 函數(shù)分步實(shí)現(xiàn)。在 python 中可以通過 merge 函數(shù)一次性實(shí)現(xiàn)。下面建立 df1 數(shù)據(jù)表,用于和 df 數(shù)據(jù)表進(jìn)行合并。
- #創(chuàng)建df1數(shù)據(jù)表
- df1=pd.DataFrame({"id":[1001,1002,1003,1004,1005,1006,1007,1008],
- "gender":['male','female','male','female','male','female','male','female'],
- "pay":['Y','N','Y','Y','N','Y','N','Y',],
- "m-point":[10,12,20,40,40,40,30,20]})

使用 merge 函數(shù)對(duì)兩個(gè)數(shù)據(jù)表進(jìn)行合并,合并的方式為 inner,將兩個(gè)數(shù)據(jù)表中共有的數(shù)據(jù)匹配到一起生成新的數(shù)據(jù)表。并命名為 df_inner。
- #數(shù)據(jù)表匹配合并,inner模式
- df_inner=pd.merge(df,df1,how='inner')

除了 inner 方式以外,合并的方式還有 left,right 和 outer 方式。這幾種方式的差別在我其他的文章中有詳細(xì)的說明和對(duì)比。
- #其他數(shù)據(jù)表匹配模式
- df_left=pd.merge(df,df1,how='left')
- df_right=pd.merge(df,df1,how='right')
- df_outer=pd.merge(df,df1,how='outer')
設(shè)置索引列
完成數(shù)據(jù)表的合并后,我們對(duì) df_inner 數(shù)據(jù)表設(shè)置索引列,索引列的功能很多,可以進(jìn)行數(shù)據(jù)提取,匯總,也可以進(jìn)行數(shù)據(jù)篩選等。
設(shè)置索引的函數(shù)為 set_index。
- #設(shè)置索引列
- df_inner.set_index('id')

排序(按索引,按數(shù)值)
Excel 中可以通過數(shù)據(jù)目錄下的排序按鈕直接對(duì)數(shù)據(jù)表進(jìn)行排序,比較簡(jiǎn)單。Python 中需要使用 ort_values 函數(shù)和 sort_index 函數(shù)完成排序。

在 python 中,既可以按索引對(duì)數(shù)據(jù)表進(jìn)行排序,也可以看制定列的數(shù)值進(jìn)行排序。首先我們按 age 列中用戶的年齡對(duì)數(shù)據(jù)表進(jìn)行排序。
使用的函數(shù)為 sort_values。
- #按特定列的值排序
- df_inner.sort_values(by=['age'])

Sort_index 函數(shù)用來將數(shù)據(jù)表按索引列的值進(jìn)行排序。
- #按索引列排序
- df_inner.sort_index()

數(shù)據(jù)分組
Excel 中可以通過 VLOOKUP 函數(shù)進(jìn)行近似匹配來完成對(duì)數(shù)值的分組,或者使用“數(shù)據(jù)透視表”來完成分組。相應(yīng)的 python 中使用 where 函數(shù)完成數(shù)據(jù)分組。
Where 函數(shù)用來對(duì)數(shù)據(jù)進(jìn)行判斷和分組,下面的代碼中我們對(duì) price 列的值進(jìn)行判斷,將符合條件的分為一組,不符合條件的分為另一組,并使用 group 字段進(jìn)行標(biāo)記。
- #如果price列的值>3000,group列顯示high,否則顯示low
- df_inner['group'] = np.where(df_inner['price'] > 3000,'high','low')

除了 where 函數(shù)以外,還可以對(duì)多個(gè)字段的值進(jìn)行判斷后對(duì)數(shù)據(jù)進(jìn)行分組,下面的代碼中對(duì) city 列等于 beijing 并且 price 列大于等于 4000 的數(shù)據(jù)標(biāo)記為 1。
- #對(duì)復(fù)合多個(gè)條件的數(shù)據(jù)進(jìn)行分組標(biāo)記
- df_inner.loc[(df_inner['city'] == 'beijing') & (df_inner['price'] >= 4000), 'sign']=1

數(shù)據(jù)分列
與數(shù)據(jù)分組相反的是對(duì)數(shù)值進(jìn)行分列,Excel 中的數(shù)據(jù)目錄下提供“分列”功能。在 python 中使用 split 函數(shù)實(shí)現(xiàn)分列。

在數(shù)據(jù)表中 category 列中的數(shù)據(jù)包含有兩個(gè)信息,前面的數(shù)字為類別 id,后面的字母為 size 值。中間以連字符進(jìn)行連接。我們使用 split 函數(shù)對(duì)這個(gè)字段進(jìn)行拆分,并將拆分后的數(shù)據(jù)表匹配回原數(shù)據(jù)表中。
- #對(duì)category字段的值依次進(jìn)行分列,并創(chuàng)建數(shù)據(jù)表,索引值為df_inner的索引列,列名稱為category和size
- pd.DataFrame((x.split('-') for x in df_inner['category']),index=df_inner.index,columns=['category','size'])

- #將完成分列后的數(shù)據(jù)表與原df_inner數(shù)據(jù)表進(jìn)行匹配
- df_inner=pd.merge(df_inner,split,right_index=True, left_index=True)

05 數(shù)據(jù)提取
第五部分是數(shù)據(jù)提取,也是數(shù)據(jù)分析中最常見的一個(gè)工作。這部分主要使用三個(gè)函數(shù),loc,iloc 和 ix,loc 函數(shù)按標(biāo)簽值進(jìn)行提取,iloc 按位置進(jìn)行提取,ix 可以同時(shí)按標(biāo)簽和位置進(jìn)行提取。下面介紹每一種函數(shù)的使用方法。
按標(biāo)簽提取(loc)
Loc 函數(shù)按數(shù)據(jù)表的索引標(biāo)簽進(jìn)行提取,下面的代碼中提取了索引列為 3 的單條數(shù)據(jù)。
- #按索引提取單行的數(shù)值
- df_inner.loc[3]
- id 1004
- date 2013-01-05 00:00:00
- city shenzhen
- category 110-C
- age 32
- price 5433
- gender female
- m-point 40
- pay Y
- group high
- sign NaN
- category_1 110
- size C
- Name: 3, dtype: object
使用冒號(hào)可以限定提取數(shù)據(jù)的范圍,冒號(hào)前面為開始的標(biāo)簽值,后面為結(jié)束的標(biāo)簽值。下面提取了 0 到 5 的數(shù)據(jù)行。
- #按索引提取區(qū)域行數(shù)值
- df_inner.loc[0:5]

Reset_index 函數(shù)用于恢復(fù)索引,這里我們重新將 date 字段的日期設(shè)置為數(shù)據(jù)表的索引,并按日期進(jìn)行數(shù)據(jù)提取。
- #重設(shè)索引
- df_inner.reset_index()

- #設(shè)置日期為索引
- df_inner=df_inner.set_index('date')

使用冒號(hào)限定提取數(shù)據(jù)的范圍,冒號(hào)前面為空表示從 0 開始。提取所有 2013 年 1 月 4 日以前的數(shù)據(jù)。
- #提取4日之前的所有數(shù)據(jù)
- df_inner[:'2013-01-04']

按位置提取(iloc)
使用 iloc 函數(shù)按位置對(duì)數(shù)據(jù)表中的數(shù)據(jù)進(jìn)行提取,這里冒號(hào)前后的數(shù)字不再是索引的標(biāo)簽名稱,而是數(shù)據(jù)所在的位置,從 0 開始。
- #使用iloc按位置區(qū)域提取數(shù)據(jù)
- df_inner.iloc[:3,:2]

iloc 函數(shù)除了可以按區(qū)域提取數(shù)據(jù),還可以按位置逐條提取,前面方括號(hào)中的 0,2,5 表示數(shù)據(jù)所在行的位置,后面方括號(hào)中的數(shù)表示所在列的位置。
- #使用iloc按位置單獨(dú)提取數(shù)據(jù)
- df_inner.iloc[[0,2,5],[4,5]]

按標(biāo)簽和位置提取(ix)
ix 是 loc 和 iloc 的混合,既能按索引標(biāo)簽提取,也能按位置進(jìn)行數(shù)據(jù)提取。下面代碼中行的位置按索引日期設(shè)置,列按位置設(shè)置。
- #使用ix按索引標(biāo)簽和位置混合提取數(shù)據(jù)
- df_inner.ix[:'2013-01-03',:4]

按條件提取(區(qū)域和條件值)
除了按標(biāo)簽和位置提起數(shù)據(jù)以外,還可以按具體的條件進(jìn)行數(shù)據(jù)。下面使用 loc 和 isin 兩個(gè)函數(shù)配合使用,按指定條件對(duì)數(shù)據(jù)進(jìn)行提取 。
使用 isin 函數(shù)對(duì) city 中的值是否為 beijing 進(jìn)行判斷。
- #判斷city列的值是否為beijing
- df_inner['city'].isin(['beijing'])
- date
- 2013-01-02 True
- 2013-01-05 False
- 2013-01-07 True
- 2013-01-06 False
- 2013-01-03 False
- 2013-01-04 False
- Name: city, dtype: bool
將 isin 函數(shù)嵌套到 loc 的數(shù)據(jù)提取函數(shù)中,將判斷結(jié)果為 Ture 數(shù)據(jù)提取出來。這里我們把判斷條件改為 city 值是否為 beijing 和 shanghai。如果是就把這條數(shù)據(jù)提取出來。
- #先判斷city列里是否包含beijing和shanghai,然后將復(fù)合條件的數(shù)據(jù)提取出來。
- df_inner.loc[df_inner['city'].isin(['beijing','shanghai'])]

數(shù)值提取還可以完成類似數(shù)據(jù)分列的工作,從合并的數(shù)值中提取出制定的數(shù)值。
- category=df_inner['category']
- 0 100-A
- 3 110-C
- 5 130-F
- 4 210-A
- 1 100-B
- 2 110-A
Name: category, dtype:
object
- #提取前三個(gè)字符,并生成數(shù)據(jù)表
- pd.DataFrame(category.str[:3])

06 數(shù)據(jù)篩選
第六部分為數(shù)據(jù)篩選,使用與,或,非三個(gè)條件配合大于,小于和等于對(duì)數(shù)據(jù)進(jìn)行篩選,并進(jìn)行計(jì)數(shù)和求和。與 excel 中的篩選功能和 countifs 和 sumifs 功能相似。
按條件篩選(與,或,非)
Excel 數(shù)據(jù)目錄下提供了“篩選”功能,用于對(duì)數(shù)據(jù)表按不同的條件進(jìn)行篩選。Python 中使用 loc 函數(shù)配合篩選條件來完成篩選功能。配合 sum 和 count 函數(shù)還能實(shí)現(xiàn) excel 中 sumif 和 countif 函數(shù)的功能。

使用“與”條件進(jìn)行篩選,條件是年齡大于 25 歲,并且城市為 beijing。篩選后只有一條數(shù)據(jù)符合要求。
- #使用“與”條件進(jìn)行篩選
- df_inner.loc[(df_inner['age'] > 25) & (df_inner['city'] == 'beijing'), ['id','city','age','category','gender']]

使用“或”條件進(jìn)行篩選,年齡大于 25 歲或城市為 beijing。篩選后有 6 條數(shù)據(jù)符合要求。
- #使用“或”條件篩選
- df_inner.loc[(df_inner['age'] > 25) | (df_inner['city'] == 'beijing'), ['id','city','age','category','gender']].sort
- (['age'])

在前面的代碼后增加 price 字段以及 sum 函數(shù),按篩選后的結(jié)果將 price 字段值進(jìn)行求和,相當(dāng)于 excel 中 sumifs 的功能。
- #對(duì)篩選后的數(shù)據(jù)按price字段進(jìn)行求和
- df_inner.loc[(df_inner['age'] > 25) | (df_inner['city'] == 'beijing'),
- ['id','city','age','category','gender','price']].sort(['age']).price.sum()
- 19796
使用“非”條件進(jìn)行篩選,城市不等于 beijing。符合條件的數(shù)據(jù)有 4 條。將篩選結(jié)果按 id 列進(jìn)行排序。
- #使用“非”條件進(jìn)行篩選
- df_inner.loc[(df_inner['city'] != 'beijing'), ['id','city','age','category','gender']].sort(['id'])

在前面的代碼后面增加 city 列,并使用 count 函數(shù)進(jìn)行計(jì)數(shù)。相當(dāng)于 excel 中的 countifs 函數(shù)的功能。
- #對(duì)篩選后的數(shù)據(jù)按city列進(jìn)行計(jì)數(shù)
- df_inner.loc[(df_inner['city'] != 'beijing'), ['id','city','age','category','gender']].sort(['id']).city.count()
- 4
還有一種篩選的方式是用 query 函數(shù)。下面是具體的代碼和篩選結(jié)果。
- #使用query函數(shù)進(jìn)行篩選
- df_inner.query('city == ["beijing", "shanghai"]')

在前面的代碼后增加 price 字段和 sum 函數(shù)。對(duì)篩選后的 price 字段進(jìn)行求和,相當(dāng)于 excel 中的 sumifs 函數(shù)的功能。
- #對(duì)篩選后的結(jié)果按price進(jìn)行求和
- df_inner.query('city == ["beijing", "shanghai"]').price.sum()
- 12230
這是第三篇,介紹第 7-9 部分的內(nèi)容,數(shù)據(jù)匯總,數(shù)據(jù)統(tǒng)計(jì),和數(shù)據(jù)輸出。

07 數(shù)據(jù)匯總
第七部分是對(duì)數(shù)據(jù)進(jìn)行分類匯總,Excel 中使用分類匯總和數(shù)據(jù)透視可以按特定維度對(duì)數(shù)據(jù)進(jìn)行匯總,python 中使用的主要函數(shù)是 groupby 和 pivot_table。下面分別介紹這兩個(gè)函數(shù)的使用方法。
分類匯總
Excel 的數(shù)據(jù)目錄下提供了“分類匯總”功能,可以按指定的字段和匯總方式對(duì)數(shù)據(jù)表進(jìn)行匯總。Python 中通過 Groupby 函數(shù)完成相應(yīng)的操作,并可以支持多級(jí)分類匯總。

Groupby 是進(jìn)行分類匯總的函數(shù),使用方法很簡(jiǎn)單,制定要分組的列名稱就可以,也可以同時(shí)制定多個(gè)列名稱,groupby 按列名稱出現(xiàn)的順序進(jìn)行分組。同時(shí)要制定分組后的匯總方式,常見的是計(jì)數(shù)和求和兩種。
- #對(duì)所有列進(jìn)行計(jì)數(shù)匯總
- df_inner.groupby('city').count()

可以在 groupby 中設(shè)置列名稱來對(duì)特定的列進(jìn)行匯總。下面的代碼中按城市對(duì) id 字段進(jìn)行匯總計(jì)數(shù)。
- #對(duì)特定的ID列進(jìn)行計(jì)數(shù)匯總
- df_inner.groupby('city')['id'].count()
- city
- beijing 2
- guangzhou 1
- shanghai 2
- shenzhen 1
- Name: id, dtype: int64
- Read more: http://bluewhale.cc/2017-04-21/use-python-for-data-analysis-like-excel-3.html#ixzz5rvDOLa9f
在前面的基礎(chǔ)上增加第二個(gè)列名稱,分布對(duì) city 和 size 兩個(gè)字段進(jìn)行計(jì)數(shù)匯總。
- #對(duì)兩個(gè)字段進(jìn)行匯總計(jì)數(shù)
- df_inner.groupby(['city','size'])['id'].count()
- city size
- beijing A 1
- F 1
- guangzhou A 1
- shanghai A 1
- B 1
- shenzhen C 1
- Name: id, dtype: int64
- Read more: http://bluewhale.cc/2017-04-21/use-python-for-data-analysis-like-excel-3.html#ixzz5rvDL89Gn
除了計(jì)數(shù)和求和外,還可以對(duì)匯總后的數(shù)據(jù)同時(shí)按多個(gè)維度進(jìn)行計(jì)算,下面的代碼中按城市對(duì) price 字段進(jìn)行匯總,并分別計(jì)算 price 的數(shù)量,總金額和平均金額。
- #對(duì)city字段進(jìn)行匯總并計(jì)算price的合計(jì)和均值。
- df_inner.groupby('city')['price'].agg([len,np.sum, np.mean])

數(shù)據(jù)透視
Excel 中的插入目錄下提供“數(shù)據(jù)透視表”功能對(duì)數(shù)據(jù)表按特定維度進(jìn)行匯總。Python 中也提供了數(shù)據(jù)透視表功能。通過 pivot_table 函數(shù)實(shí)現(xiàn)同樣的效果。

數(shù)據(jù)透視表也是常用的一種數(shù)據(jù)分類匯總方式,并且功能上比 groupby 要強(qiáng)大一些。下面的代碼中設(shè)定 city 為行字段,size 為列字段,price 為值字段。分別計(jì)算 price 的數(shù)量和金額并且按行與列進(jìn)行匯總。
- #數(shù)據(jù)透視表
- pd.pivot_table(df_inner,index=["city"],values=["price"],columns=["size"],aggfunc=[len,np.sum],fill_value=0,margins=True)

08 數(shù)據(jù)統(tǒng)計(jì)
第九部分為數(shù)據(jù)統(tǒng)計(jì),這里主要介紹數(shù)據(jù)采樣,標(biāo)準(zhǔn)差,協(xié)方差和相關(guān)系數(shù)的使用方法。
數(shù)據(jù)采樣
Excel 的數(shù)據(jù)分析功能中提供了數(shù)據(jù)抽樣的功能,如下圖所示。Python 通過 sample 函數(shù)完成數(shù)據(jù)采樣。

Sample 是進(jìn)行數(shù)據(jù)采樣的函數(shù),設(shè)置 n 的數(shù)量就可以了。函數(shù)自動(dòng)返回參與的結(jié)果。
- #簡(jiǎn)單的數(shù)據(jù)采樣
- df_inner.sample(n=3)

Weights 參數(shù)是采樣的權(quán)重,通過設(shè)置不同的權(quán)重可以更改采樣的結(jié)果,權(quán)重高的數(shù)據(jù)將更有希望被選中。這里手動(dòng)設(shè)置 6 條數(shù)據(jù)的權(quán)重值。將前面 4 個(gè)設(shè)置為 0,后面兩個(gè)分別設(shè)置為 0.5。
- #手動(dòng)設(shè)置采樣權(quán)重
- weights = [0, 0, 0, 0, 0.5, 0.5]
- df_inner.sample(n=2, weights=weights)
- Read more: http://bluewhale.cc/2017-04-21/use-python-for-data-analysis-like-excel-3.html#ixzz5rvCvwN2y

從采樣結(jié)果中可以看出,后兩條權(quán)重高的數(shù)據(jù)被選中。

Sample 函數(shù)中還有一個(gè)參數(shù) replace,用來設(shè)置采樣后是否放回。
- #采樣后不放回
- df_inner.sample(n=6, replace=False)

- #采樣后放回
- df_inner.sample(n=6, replace=True)

描述統(tǒng)計(jì)
Excel 中的數(shù)據(jù)分析中提供了描述統(tǒng)計(jì)的功能。Python 中可以通過 Describe 對(duì)數(shù)據(jù)進(jìn)行描述統(tǒng)計(jì)。

描述統(tǒng)計(jì)
Describe 函數(shù)是進(jìn)行描述統(tǒng)計(jì)的函數(shù),自動(dòng)生成數(shù)據(jù)的數(shù)量,均值,標(biāo)準(zhǔn)差等數(shù)據(jù)。下面的代碼中對(duì)數(shù)據(jù)表進(jìn)行描述統(tǒng)計(jì),并使用 round 函數(shù)設(shè)置結(jié)果顯示的小數(shù)位。并對(duì)結(jié)果數(shù)據(jù)進(jìn)行轉(zhuǎn)置。
- #數(shù)據(jù)表描述性統(tǒng)計(jì)
- df_inner.describe().round(2).T

標(biāo)準(zhǔn)差
Python 中的 Std 函數(shù)用來接算特定數(shù)據(jù)列的標(biāo)準(zhǔn)差。
- #標(biāo)準(zhǔn)差
- df_inner['price'].std()
- 1523.3516556155596
協(xié)方差
Excel 中的數(shù)據(jù)分析功能中提供協(xié)方差的計(jì)算,python 中通過 cov 函數(shù)計(jì)算兩個(gè)字段或數(shù)據(jù)表中各字段間的協(xié)方差。

Cov 函數(shù)用來計(jì)算兩個(gè)字段間的協(xié)方差,可以只對(duì)特定字段進(jìn)行計(jì)算,也可以對(duì)整個(gè)數(shù)據(jù)表中各個(gè)列之間進(jìn)行計(jì)算。
- #兩個(gè)字段間的協(xié)方差
- df_inner['price'].cov(df_inner['m-point'])
- 17263.200000000001
- #數(shù)據(jù)表中所有字段間的協(xié)方差
- df_inner.cov()

相關(guān)分析
Excel 的數(shù)據(jù)分析功能中提供了相關(guān)系數(shù)的計(jì)算功能,python 中則通過 corr 函數(shù)完成相關(guān)分析的操作,并返回相關(guān)系數(shù)。

Corr 函數(shù)用來計(jì)算數(shù)據(jù)間的相關(guān)系數(shù),可以單獨(dú)對(duì)特定數(shù)據(jù)進(jìn)行計(jì)算,也可以對(duì)整個(gè)數(shù)據(jù)表中各個(gè)列進(jìn)行計(jì)算。相關(guān)系數(shù)在-1 到 1 之間,接近 1 為正相關(guān),接近-1 為負(fù)相關(guān),0 為不相關(guān)。
- #相關(guān)性分析
- df_inner['price'].corr(df_inner['m-point'])
- 0.77466555617085264
- #數(shù)據(jù)表相關(guān)性分析
- df_inner.corr()

09 數(shù)據(jù)輸出
第九部分是數(shù)據(jù)輸出,處理和分析完的數(shù)據(jù)可以輸出為 xlsx 格式和 csv 格式。
寫入 excel
- #輸出到 excel 格式
- df_inner.to_excel('excel_to_python.xlsx', sheet_name='bluewhale_cc')

excel
寫入 csv
- #輸出到 CSV 格式
- df_inner.to_csv('excel_to_python.csv')
在數(shù)據(jù)處理的過程中,大部分基礎(chǔ)工作是重復(fù)和機(jī)械的,對(duì)于這部分基礎(chǔ)工作,我們可以使用自定義函數(shù)進(jìn)行自動(dòng)化。以下簡(jiǎn)單介紹對(duì)數(shù)據(jù)表信息獲取自動(dòng)化處理。
- 創(chuàng)建數(shù)據(jù)表
- df = pd.DataFrame({"id":[1001,1002,1003,1004,1005,1006],
- "date":pd.date_range('20130102', periods=6),
- "city":['Beijing ', 'SH', ' guangzhou ', 'Shenzhen', 'shanghai', 'BEIJING '],
- "age":[23,44,54,32,34,32],
- "category":['100-A','100-B','110-A','110-C','210-A','130-F'],
- "price":[1200,np.nan,2133,5433,np.nan,4432]},
- columns =['id','date','city','category','age','price'])
- Read more: http://bluewhale.cc/2017-04-21/use-python-for-data-analysis-like-excel-3.html#ixzz5rvBC8kaw
- #創(chuàng)建自定義函數(shù)
- def table_info(x):
- shape=x.shape
- types=x.dtypes
- colums=x.columns
- print("數(shù)據(jù)維度(行,列):\n",shape)
- print("數(shù)據(jù)格式:\n",types)
- print("列名稱:\n",colums)
- Read more: http://bluewhale.cc/2017-04-21/use-python-for-data-analysis-like-excel-3.html#ixzz5rvBC8kaw
- #調(diào)用自定義函數(shù)獲取df數(shù)據(jù)表信息并輸出結(jié)果
- table_info(df)
- 數(shù)據(jù)維度(行,列):
- (6, 6)
- 數(shù)據(jù)格式:
- id int64
- date datetime64[ns]
- city object
- category object
- age int64
- price float64
- dtype: object
- 列名稱:
- Index(['id', 'date', 'city', 'category', 'age', 'price'], dtype='object')
- Read more: http://bluewhale.cc/2017-04-21/use-python-for-data-analysis-like-excel-3.html#ixzz5rvBJs6Fv
以上就是用 Python 做數(shù)據(jù)分析的基本內(nèi)容。