數據分析從零開始實戰 | 基礎篇(四)
- 2020 年 2 月 13 日
- 筆記
本系列學習筆記參考書籍:《數據分析實戰》托馬茲·卓巴斯
一 基本知識概要
1.利用Pandas檢索HTML頁面(read_html函數) 2.實戰訓練使用read_html函數直接獲取頁面數據 3.基本數據處理:表頭處理、dropna和fillna詳解 4.基本數據可視化分析案例
二 開始動手動腦
1.Pandas的read_html函數
這裡我們要介紹的是Pandas里解析HTML頁面的函數:read_html
。

查看源碼後我們可以看出,該函數的參數比較多,下面我挑重點給大家解釋幾個。 (1)io
(最關鍵參數)
源碼注釋
A URL, a file-like object, or a raw string containing HTML. Note that lxml only accepts the http, ftp and file url protocols. If you have a URL that starts with ``'https'`` you might try removing the ``'s'``.
我的理解
數據地址(網頁地址、包含HTML的文件地址或者字元串)。 注意lxml只接受HTTP、FTP和文件URL協議。 如果你有以「https」開頭的URL,你可以嘗試刪除「s」再傳入參數。
(2)match
源碼注釋
str or compiled regular expression, optional The set of tables containing text matching this regex or string will be returned. Unless the HTML is extremely simple you will probably need to pass a non-empty string here. Defaults to '.+' (match any non-empty string). The default value will return all tables contained on a page. This value is converted to a regular expression so that there is consistent behavior between Beautiful Soup and lxml.
我的理解
字元串或編譯的正則表達式,可選 包含與此正則表達式或字元串匹配的文本的一組表將返回。 除非HTML非常簡單,否則您可能需要在此處傳遞一個非空字元串。 默認為「.+」(匹配任何非空字元串)。默認值將返回頁面上包含的所有<table>標籤包含的表格。 該值將轉換為正則表達式,以便Beautiful Soup和LXML之間一致。
(3)flavor
源碼注釋
flavor : str or None, container of strings The parsing engine to use. 'bs4' and 'html5lib' are synonymous with each other, they are both there for backwards compatibility. The default of ``None`` tries to use ``lxml`` to parse and if that fails it falls back on ``bs4`` + ``html5lib``.
我的理解
要使用的解析引擎。'bs4'和'html5lib'是彼此的同義詞, 它們都是為了向後兼容。默認為空,嘗試用於lxml解析的默認值, 如果失敗,則使用bs4和 html5lib。
2.數據基本處理
(1)處理列名
# 處理列名 import re # 匹配字元串中任意空白字元的正則表達式 space = re.compile(r"s+") def fix_string_spaces(columnsToFix): ''' 將列名中的空白字元轉變成下劃線 ''' tempColumnNames = [] # 保存處理後的列名 # 循環處理所有列 for item in columnsToFix: # 匹配到 if space.search(item): # 處理並加入列表 tempColumnNames.append('_'.join((space.split(item)))) ''' 這句有點長涉及到列表的一些操作,我解釋一下 str1.split(str2) str1 表示被分隔的字元串;str2表示分隔字元串 str3.join(list1) str2 表示按什麼字元串進行連接;list1表示待連接的列表 list2.append(str4) 表示在列表list2的末尾添加str4這個元素 ''' else : # 否則直接加入列表 tempColumnNames.append(item) return tempColumnNames
上面這段程式碼來自書本,其目的是處理列名,將列名里為空的字元轉變成-
符號,仔細一想,其實這個是可以通用的,比如處理某行數據里為空的,處理某個列表裡為空的數據等,復用性很強。
(2)對缺失數據處理之dropna函數
dropna()
函數:對缺失的數據進行過濾。

常用參數解析: axis
:
源碼注釋
axis : {0 or 'index', 1 or 'columns'}, default 0 Determine if rows or columns which contain missing values are removed. * 0, or 'index' : Drop rows which contain missing values. * 1, or 'columns' : Drop columns which contain missing value. .. deprecated:: 0.23.0: Pass tuple or list to drop on multiple axes.
我的理解
少用,默認值為0,表示刪除包含缺少值的行;值為1,表示刪除包含缺少值的列。
how
:
源碼注釋
how : {'any', 'all'}, default 'any' Determine if row or column is removed from DataFrame, when we have at least one NA or all NA. * 'any' : If any NA values are present, drop that row or column. * 'all' : If all values are NA, drop that row or column.
我的理解
默認值為any,表示如果存在任何NA(空)值,則刪除該行或列; 值為all,表示如果全都是NA值,則刪除該行或列。
thresh
:
源碼注釋
thresh : int, optional Require that many non-NA values.
我的理解
不為NA的個數,滿足要求的行保留,不滿足的行被刪除。
inplace
:
源碼注釋
inplace : bool, default False If True, do operation inplace and return None.
我的理解
默認為False,表示不在原對象上操作, 而是複製一個新的對象進行操作並返回; 值為True時,表示直接在原對象上進行操作。
(3)對缺失數據處理之fillna函數
fillna()
函數:用指定值或插值的方法填充缺失數據。

常用參數解析: value
:
源碼注釋
value : scalar, dict, Series, or DataFrame Value to use to fill holes (e.g. 0), alternately a dict/Series/DataFrame of values specifying which value to use for each index (for a Series) or column (for a DataFrame). (values not in the dict/Series/DataFrame will not be filled). This value cannot be a list.
我的理解
簡單點說,就是替換NA(空值)的值。如果是直接給值,表示全部替換; 如果是字典: {列名:替換值} 表示替換掉該列包含的所有空值。
method
:
源碼注釋
method : {'backfill', 'bfill', 'pad', 'ffill', None}, default None Method to use for filling holes in reindexed Series pad / ffill: propagate last valid observation forward to next valid backfill / bfill: use NEXT valid observation to fill gap
我的理解
在重新索引系列中填充空白值的方法。 pad / ffill:按列檢索,將最後一次不為空的值賦給下一個空值。 backfill / bfill:按列檢索,將下一個不為空的值賦給該空值。 注意:該參數不可與value 同時存在
limit
:
源碼注釋
limit : int, default None If method is specified, this is the maximum number of consecutive. NaN values to forward/backward fill. In other words, if there is a gap with more than this number of consecutive NaNs, it will only be partially filled. If method is not specified, this is the maximum number of entries along the entire axis where NaNs will be filled. Must be greater than 0 if not None.
我的理解
其實很簡單,就是按列搜索空值,然後limit的值表示最大的連續填充空值個數。 比如:limit=2,表示一列中從上到下搜索,只替換前兩個空值,後面都不替換。
吐個槽:別看源碼里的英文注釋單詞都很簡單,但,太簡單了,根本連不成句子,我都是一個個實踐+表面翻譯,然後才能弄明白參數的意思。
3.數據爬取實戰訓練
五行程式碼爬取2019富豪榜(60億美元以上的)
import pandas as pd # 排行榜 for i in range(15): # 頁面地址 url = "https://www.phb123.com/renwu/fuhao/shishi_%d.html" % (i+1) # 調用read_html函數,解析頁面獲取數據 List url_read = pd.read_html(url, header=0)[0] # 將數據存入csv文件 url_read.to_csv(r'rich_list.csv', mode='a', encoding='utf_8_sig', header=0, index=False)
頁面數據:

爬取結果:

通過上面實戰,你需要知道: 1、不要覺得怎麼這麼簡單啊(是因為我找好了網站,這個網站數據里只有一個table,數據也比較乾淨); 2、真正工作中網站可能是不配合的,數據可能是不配合的,這個時候最好的方法是見仁見智,多看源程式碼。
4.數據可視化分析實戰訓練
基於我們上面拿到的數據,我們做個簡單的數據可視化和分析報告。 上面我們已經拿到了2019富豪榜(60億美元以上的)的數據,包含排名、姓名、財富數額、財富來源、國家這些資訊,明確數據屬性後,我們就該想一下我們能從那些方面去分析那些問題? 我想到的幾個方面: (1)排行榜上各個國家的人數各多少?那些國家最多? (2)那些公司上榜的人數最多? (3)排行榜上的人所在的行業分布?
(0)讀取數據和數據可視化
讀取數據我們直接利用pandans的read_csv函數。
import pandas as pd # 原始數據文件路徑 rpath_csv = 'rich_list.csv' # 讀取數據 csv_read = pd.read_csv(rpath_csv) # 提取出來的數據是pandans的Series對象 # 後期處理可以直接轉換成列表 name_list = csv_read["名字"] money_list = csv_read["財富(10億美元)"] company_list = csv_read["財富來源"] country_list = csv_read["國家/地區"]
數據可視化,我們從最簡單的pyecharts模組,安裝方法如下。
pip install pyecharts
點擊了解:pyecharts基本使用詳解
(1)排行榜上各個國家的人數各多少?那些國家最多?
# 排行榜上各個國家的人數各多少?那些國家最多? """ 1、統計數據 利用collections模組的Counter函數 """ country_list = list(country_list) from collections import Counter dict_number = Counter(country_list) """ 2、數據可視化 利用pyecharts模組的Bar類 """ bar = Bar("富豪國家分布柱狀圖") bar.add("富豪", key_list, values_list, is_more_utils=True, is_datazoom_show=True, xaxis_interval=0, xaxis_rotate=30, yaxis_rotate=30, mark_line=["average"], mark_point=["max", "min"]) bar.render("rich_country.html")

從上面數據,我們可以很明顯的發現,富豪榜上富豪的國籍,美國居多,而且可以說是遙遙領先,總共是300
人,美國國籍的有106
人,佔了總數據的1/3
還多,這個比較好理解,美國一直是一個超級大國,各個方面的發展都位列全球前列。
位列第二的是中國,佔了43
人,也是特別多的,而且對於中國,發展到現在是非常非常不容易的,從1949年成立,到今年2019年,建國70年,從「為中華之崛起而讀書」到「為實現中國夢、建設富強民主文明和諧美麗的社會主義現代化強國而奮鬥」,作為中國人,我是驕傲的。
第三名是德國和俄羅斯,各占20
人,德國是個工業大國,歐洲最大經濟體,所以德國的強健是顯而易見的,另外俄羅斯,世介面積最大的國家,曾經蘇聯也是世界第二經濟強國,雖然蘇聯解體後不如從前,但近幾年普京執政,經濟穩步回升。
再後面的國家中以歐洲國家居多,其中第五是印度,其科技實力十分發達。
(2)那些公司上榜的人數最多?

注意哦~能上這個榜的,財富最低都是60億美元,從統計數據來看,瑪氏公司上榜人數最多,有6個上榜的富豪來自瑪氏公司,其次是沃爾瑪百貨有限公司,有3個人來自該公司,這兩個公司都是日化類公司,接下來的:微軟、Facebook、Google都是科技類公司。

瑪氏公司百度百科

沃爾瑪公司百度百科
不查一下,我還真不知道,原來「餓貨,快來條士力架」的士力架、「德芙,縱享絲滑」的德芙是來自一家公司的,而且是瑪氏公司的,此處雙擊666。另外沃爾瑪在2018年被評選為世界五百強的第一位,莫種意義來說,這就是宇宙最強公司啊~(小時候我一直以為富迪是最厲害的超市,長大後我又以為萬達是最厲害的超市,現在,我知道了,是沃爾瑪!)
(3)排行榜上的人所在的行業分布?
這部分其實是不好做的,因為我們獲取到的數據里沒有直接和行業相連的數據,唯一能和行業有點聯繫的就是公司,這就需要我們通過公司名稱去判斷(或者在網上獲取)該公司的類別屬性,比如是互聯網公司,還是傳統行業等等方面。
【完】