手把手教你用 Pandas 分析全國城市房價

大家好,我是小五🧐

Pandas靈活好用,能夠完成複雜的、重複的、批量的數據處理。

本文教你利用Pandas爬取房價,以及分析全國城市的房價。

Pandas在配合做網絡數據採集爬蟲時,也能發揮其優勢,可承擔數據調用數據存儲的工作。將數據存入DataFrame後,可直接進入下一步分析。本例以獲取某房產網站中房價爲目標,來體驗一下Pandas的便捷之處。

首先利用requests(需要安裝)庫獲取單個小區的平均價格:

import requests # 安裝:pip install requests  
  
# 創建一個Session  
  
s = requests.Session()  
  
# 訪問小區頁面  
  
xq = s.get('https://bj.lianjia.com/xiaoqu/1111027382589/')  
  
# 查看頁面源碼  
  
xq.text  
  
# 找到價格位置附近的源碼爲:  
  
# <span class="xiaoquUnitPrice">95137</span>  
  
# 切分與解析  
  
xq.text.split('xiaoquUnitPrice">')[1].split('</span>')[0]  
  
# '93754'  

最終得到這個小區的平均房價。這裏使用了將目標信息兩邊的信息進行切片、形成列表再讀取的方法。也可以用第三方庫Beautiful Soup 4來解析。Beautiful Soup是一個可以從HTML或XML文件中提取數據的Python庫,它能夠通過解析源碼來方便地獲取指定信息。

我們構建獲取小區名稱和平均房價的函數:

# 獲取小區名稱的函數  
  
def pa_name(x):  
  
    xq = s.get(f'https://bj.lianjia.com/xiaoqu/{x}/')  
  
    name = xq.text.split('detailTitle">')[1].split('</h1>')[0]  
  
    return name  
  
  
# 獲取平均房價的函數  
  
def pa_price(x):  
  
    xq = s.get(f'https://bj.lianjia.com/xiaoqu/{x}/')  
  
    price = xq.text.split('xiaoquUnitPrice">')[1].split('</span>')[0]  
  
    return price  

接下來利用Pandas執行爬蟲獲取信息:

# 小區列表  
  
xqs = [11110273775951111027382589,  
       11110273786111111027374569,  
       11110273780691111027374228,  
       116964627385853]  
  
# 構造數據  
  
df = pd.DataFrame(xqs, columns=['小區'])  
  
  
# 爬取小區名  
  
df['小區名'] = df.小區.apply(lambda x: pa_name(x))  
  
# 爬取房價  
  
df['房價'] = df.小區.apply(lambda x: pa_price(x))  
  
# 查看結果  
  
df  
  
'''  
                小區      小區名      房價  
0    1111027377595     瞰都國際   73361  
1    1111027382589  棕櫚泉國際公寓   93754  
2    1111027378611     南十里居   56459  
3    1111027374569     觀湖國際   88661  
4    1111027378069     麗水嘉園   76827  
5    1111027374228  泛海國際碧海園   97061  
6  116964627385853  東山condo  145965  
'''
  

可以先用Python的類改造函數,再用鏈式方法調用:

# 爬蟲類  
class PaChong(object):  
    def __init__(self, x):  
        self.s = requests.session()  
        self.xq = self.s.get(f'https://bj.lianjia.com/xiaoqu/{x}/')  
        self.name = self.xq.text.split('detailTitle">')[1].split('</h1>')[0]  
        self.price = self.xq.text.split('xiaoquUnitPrice">')[1].split('</span>')[0]  
  
# 爬取數據  
  
(  
    df  
    .assign(小區名=df.小區.apply(lambda x: PaChong(x).name))  
    .assign(房價=df.小區.apply(lambda x: PaChong(x).price))  
)  

以上網站可能會改版,代碼不適用時需要調整爬蟲代碼。

全國城市房價分析

中國主要城市的房價可以從https://www.creprice.cn/rank/index.html獲取。該網頁中會顯示上一個月的房價排行情況,先複製前20個城市的數據,然後使用pd.read_clipboard()讀取。我們來分析一下該月的數據(下例中用的是2020年10月數據)。

import pandas as pd  
  
import matplotlib.pyplot as plt  
  
plt.rcParams['figure.figsize'] = (8.05.0# 固定顯示大小  
  
plt.rcParams['font.family'] = ['sans-serif'# 設置中文字體  
  
plt.rcParams['font.sans-serif'] = ['SimHei'# 設置中文字體  
  
plt.rcParams['axes.unicode_minus'] = False # 顯示負號  
  
dfr = pd.read_clipboard()  
  
  
# 取源數據  
  
dfr.head()  
  
'''  
  
   序號 城市名稱 平均單價(元/㎡)  環比 同比  
0   1   深圳    78,722  +2.61%  +20.44%  
1   2   北京    63,554  -0.82%    -1.2%   
2   3   上海    58,831   +0.4%    +9.7%  
3   4   廈門    48,169  -0.61%   +9.52%  
4   5   廣州    38,351  -1.64%  +13.79%  
'''
  

查看數據類型:

dfr.dtypes  
  
'''  
序號            int64  
城市名稱         object  
平均單價(元/㎡)    object  
環比           object  
同比           object  
dtype: object  
'''
  

數據都是object類型,需要對數據進行提取和類型轉換:

df = (  
    # 去掉千分位符並轉爲整型  
    dfr.assign(平均單價=dfr['平均單價(元/㎡)'].str.replace(',','').astype(int))  
    .assign(同比=dfr.同比.str[:-1].astype(float)) # 去百分號並轉爲浮點型  
    .assign(環比=dfr.環比.str[:-1].astype(float)) # 去百分號並轉爲浮點型  
    .loc[:,['城市名稱','平均單價','同比','環比']] # 重命名列   
)  
  
df.head()  
  
'''  
  城市名稱  平均單價 同比  環比  
0   深圳  78722  20.44  2.61  
1   北京  63554  -1.20 -0.82  
2   上海  58831   9.70  0.40  
3   廈門  48169   9.52 -0.61  
4   廣州  38351  13.79 -1.64  
'''
  

接下來就可以對整理好的數據進行分析了。首先看一下各城市的均價差異,數據順序無須再調整,代碼執行效果如圖1所示。

(
    df.set_index('城市名稱')
    .平均單價
    .plot
    .bar()
)
圖1 各城市平均房價

各城市平均房價同比與環比情況如圖2所示。

(  
    df.set_index('城市名稱')  
    .loc[:, '同比':'環比']  
    .plot  
    .bar()  
)  
圖2 各城市平均房價同比和環比

將同比與環比的極值用樣式標註,可見東莞異常突出,房價同比、環比均大幅上升,如圖3所示。

(  
    df.style  
    .highlight_max(color='red', subset=['同比''環比'])  
    .highlight_min(subset=['同比''環比'])  
    .format({'平均單價':"{:,.0f}"})  
    .format({'同比':"{:2}%"'環比':"{:2}%"})  
)  
圖3 各城市平均房價變化樣式圖

繪製各城市平均單價條形圖,如圖4所示。

# 條形圖  
(  
    df.style  
    .bar(subset=['平均單價'], color='yellow')  
)  
圖4 各城市平均單價樣式圖

將數據樣式進行綜合可視化:將平均單價背景色設爲漸變,並指定色系BuGn;同比、環比條形圖使用不同色系,且以0爲中點,體現正負;爲比值加百分號。最終效果如圖5所示。

(
    df.style
    .background_gradient(subset=['平均單價'], cmap='BuGn')
    .format({'同比':"{:2}%"'環比':"{:2}%"})
    .bar(subset=['同比'], 
        color=['#ffe4e4','#bbf9ce'], # 上漲、下降的顏色
        vmin=0, vmax=15# 範圍定爲以0爲基準的上下15
        align='zero'
        )
    .bar(subset=['環比'], 
        color=['red','green'], # 上漲、下降的顏色
        vmin=0, vmax=11# 範圍定爲以0爲基準的上下11
        align='zero'
        )
)
圖5 各城市平均房價綜合樣式圖

本文摘編於《深入淺出Pandas:利用Python進行數據處理與分析》,經出版方授權發佈。

最近有啥書?

深入淺出Pandas:這是一本全面覆蓋了Pandas使用者的普遍需求和痛點的著作,基於實用、易學的原則,從功能、使用、原理等多個維度對Pandas做了全方位的詳細講解,既是初學者系統學習Pandas難得的入門書,又是有經驗的Python工程師案頭必不可少的查詢手冊。


本文分享自微信公衆號 - 凹凸數據(alltodata)。
如有侵權,請聯繫 [email protected] 刪除。
本文參與“OSC源創計劃”,歡迎正在閱讀的你也加入,一起分享。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章