項目介紹
項目來源:天池大數據平臺
項目思路:針對airbnb中listings表做數據處理,探索分析以及針對經緯度以及價格做地理價格圖(pyecharts)
python:3.7.1
pyecharts:1.2.0
天池平臺的這個比賽比較常見,本文給出了地理可視化的新思路
(想看圖的直接拉到3/4就可)
模塊導入
分析思路
#數據處理包導入
import pandas as pd
import numpy as np
from scipy import stats
#畫圖包導入
import matplotlib.pyplot as plt
import seaborn as sns
#日期處理包導入
import calendar
from datetime import datetime
#jupyter notebook繪圖設置
%matplotlib inline
#中文字體正確顯示
plt.rcParams['font.sans-serif']=['SimHei']
plt.rcParams['axes.unicode_minus']=False
#警告刪除
import warnings
warnings.simplefilter(action="ignore", category=FutureWarning)
warnings.filterwarnings('ignore')
#多行輸出
from IPython.core.interactiveshell import InteractiveShell
InteractiveShell.ast_node_interactivity = "all"
# 顯示正負號與中文不顯示問題
plt.rcParams['axes.unicode_minus'] = False
sns.set_style('darkgrid', {'font.sans-serif':['SimHei', 'Arial']})
數據處理
導入數據
listings = pd.read_csv('listings.csv',parse_dates=['last_review'],dtype={'id':str,'host_id':str})# keep_default_na=False將空值設置爲不顯示方便之後處理
處理
listings.info()
- 觀察發現listings表有幾個問題:
- neighbourhood_group列存在很多空值,查看統計信息
- neighbourhood列有中文有英文,僅保留neighbourhood列中文部分
- 查看經緯度,價格,最小入住天數,365天,房東擁有房屋數中是否有異常值
- 查看房屋類型有多少種
- 查看評論數前10的id
- 查看每月評論數前十的id
- name,last_review和reviews_per_month中都存在空值,不過影響不大,name是因爲沒有命名標準,last_review爲空值有可能說明沒有評論過,沒有last_review也就沒有reviews_per_month
listings.head()
name雖然雜亂有中英文有英文但是不重要不需要處理,host_name中有錯亂的數據比如East Apartments也不重要也不需要怎麼處理,neighbourhood_group全爲空值可以刪除這列,neighbourhood可以截取爲全中文列
listings.drop(['neighbourhood_group'],axis=1,inplace=True)
listings['neighbourhood'] = listings['neighbourhood'].str.split('/',expand=True)[0]
listings.sample(3)
#通過觀察,last_review,reviews_per_month和reviews_per_month的空值是一致的
listings[listings['last_review'].isnull()]['number_of_reviews'].sum()
listings[listings['last_review'].isnull()]['reviews_per_month'].sum()
發現結果都是0
說明這些可能都是未評論房屋,將這些數據的reviews_per_month用0代替
listings.reviews_per_month.fillna(0,inplace=True)
listings[(listings['number_of_reviews']==0)].head()
listings.describe()
探索性處理
price,minimum_nights,number_of_reviews和calculated_host_listings_count等有異常值
首先看price
#通過直方圖直觀看出大部分價格在10000以內
listings.price.hist()
#縮小範圍後再次查看直方圖
listings_price1000 = listings.loc[listings['price']<1000]
listings_price1000.price.hist()
發現大部分房屋價格在200到700之間一晚,1000以上的異常值可能較多,比較符合常理,因爲airbnb本來的品牌理念就是實現空閒房屋的共享使用,大部分提供的房屋都是普通型,價格過高的不會太多
#異常值查看
listings.loc[listings['price']==68983]
#異常值查看
listings.loc[listings['price']==0]
結論是:
- 價格大部分分佈在200-700
- 異常值類別較多,且異常值和高價房屋不好判斷
- 異常值佔比非常少
區域化分析
#區域房屋數量
listings['neighbourhood'].value_counts()
fig = plt.figure(figsize=(12,4))
sns.barplot(listings['neighbourhood'].value_counts().index,listings['neighbourhood'].value_counts().values,data = listings)
plt.title('區域房屋數量直方圖',fontsize=20)
價格分析
#全北京房屋平均每晚房價是多少
listings.price.mean() #所有房屋
listings_price1000.price.mean() #價格小於1000的房屋
611.2033248980739
381.6178138595401
地理位置分析
安裝與導入地圖包
pip install echarts-countries-pypkg -i https://mirrors.aliyun.com/pypi/simple# 全球國家地圖
pip install echarts-cities-pypkg -i https://mirrors.aliyun.com/pypi/simple# 全球城市地圖
pip install echarts-china-provinces-pypkg -i https://mirrors.aliyun.com/pypi/simple# 中國省級地圖
pip install echarts-china-cities-pypkg -i https://mirrors.aliyun.com/pypi/simple# 中國市級地圖
pip install echarts-china-misc-pypkg -i https://mirrors.aliyun.com/pypi/simple # 中國區域地圖
pip install echarts-united-kingdom-pypkg -i https://mirrors.aliyun.com/pypi/simple # 英國選區圖可以用來畫與政治經濟相關的數據
數據預處理
data = pd.DataFrame(listings,columns=['id','price'])
data.head()
data_pair = []
for i in range(len(listings)):
data_pair.append((data.iloc[i][0],int(data.iloc[i][1]))) #pyecharts是不支持numpy.int的
#導入地圖庫
from pyecharts.charts import Geo
from pyecharts import options as opts
from pyecharts.globals import GeoType
def test_geo():
city = '北京'
g = Geo()
g.add_schema(maptype=city)
# 定義座標對應的名稱,添加到座標庫中 add_coordinate(name, lng, lat)
for i in range(len(data_pair)):
g.add_coordinate(listings['id'][i],listings['longitude'][i],listings['latitude'][i])
# 定義數據對
g.add('', data_pair, type_=GeoType.EFFECT_SCATTER, symbol_size=5)
# 設置樣式
g.set_series_opts(label_opts=opts.LabelOpts(is_show=False))
# 自定義分段 color 可以用取色器取色
pieces = [
{'max': 100, 'label': '100以下', 'color': '#50A3BA'},
{'min': 101, 'max': 200, 'label': '100-200', 'color': '#3700A4'},
{'min': 201, 'max': 300, 'label': '201-300', 'color': '#81AE9F'},
{'min': 301, 'max': 400, 'label': '301-400', 'color': '#E2C568'},
{'min': 401, 'max': 500, 'label': '401-500', 'color': '#FCF84D'},
{'min': 501, 'max': 600, 'label': '501-600', 'color': '#DD0200'},
{'min': 601, 'max': 700, 'label': '601-700', 'color': '#DD675E'},
{'min': 701, 'label': '701以上', 'color': '#D94E5D'} # 有下限無上限
]
# is_piecewise 是否自定義分段, 變爲true 才能生效
g.set_global_opts(
visualmap_opts=opts.VisualMapOpts(is_piecewise=True, pieces=pieces),
title_opts=opts.TitleOpts(title="{}-區域房屋以及價格分佈".format(city)),
)
return g
g = test_geo()
g.render('test_render3.html')
- 房源大部分還是密集分佈在海淀,朝陽,西城,東城,石景山,豐臺區,其他區以靠攏這幾個區爲主要房源分佈地
- 價格方面,越是密集的地方分佈越是均勻,但是延慶懷柔昌平房山等相對來說經濟不怎麼發達的區域反而價格較高,可能是因爲轟趴別墅野營農家樂的興起,所以一些可供多人居住的"豪宅"數量增多
根據區域的不同類型查看價格分佈以及數量分佈
全價格分析
listings_gbneigh=listings.groupby(by='neighbourhood')
listings_gbneigh.price.mean().sort_values(ascending=False)
fig = plt.figure(figsize=(12,6))
sns.barplot(x=listings.neighbourhood,y=listings.price,data=listings,order=listings_gbneigh.price.mean().sort_values(ascending=False).index)
1000以內價格分析
listings_gbneigh1000=listings_price1000.groupby(by='neighbourhood')
listings_gbneigh1000.price.mean().sort_values(ascending=False)
fig = plt.figure(figsize=(12,6))
sns.barplot(x=listings_price1000.neighbourhood,y=listings_price1000.price,data=listings_price1000,order=listings_gbneigh1000.price.mean().sort_values(ascending=False).index)
- 和之前的結論相似,以轟趴別墅爲主的郊區房屋每晚價格較高
根據房屋的不同類型查看價格分佈以及數量分佈
fig,axes = plt.subplots(1,3,figsize=(12,3))
sns.distplot(listings_price1000[listings_price1000.room_type=='Entire home/apt'].price,ax=axes[0],axlabel='Entire home/apt')
sns.distplot(listings_price1000[listings_price1000.room_type=='Private room'].price,ax=axes[1],axlabel='Private room',color='r')
sns.distplot(listings_price1000[listings_price1000.room_type=='Shared room'].price,ax=axes[2],axlabel='Shared room',color='green')
- 整套房屋的價格數量分佈比較平均,既有平價房也有高價房,且高價房佔比不是很低,大部分房屋價格在250-550左右,
- 而獨立房間的價格相對來說較便宜一些,這可能是因爲使用率較高的原因,價格大多在150-300之間
- 而合住房間的價格是三者最平價的,以多人民宿,青年旅舍之類的共享房屋爲主,大部分只是一個牀鋪的價格,價格大多在50-150之間
查看房源數量和房東人數的關係
#以host_id分組
df1=listings.groupby('host_id').count()['id'].to_frame() #以host_id分組,並計算每位房東的房屋數,轉換爲DT
df1['host_id'] = df1.index #將index轉換爲列
df1.reset_index(drop=True,inplace=True)
df1.rename(columns={'id':'room_num'},inplace=True)
df1 = pd.DataFrame(df1,columns=['host_id','room_num'])
print('以host_id分組:')
df1.head()
df1.room_num.max() #查看擁有最多房屋的房東的房屋數
以host_id分組:
#以room_num分組
df2=df1.groupby('room_num').count()['host_id'].to_frame() #以room_num分組,並計算擁有固定房屋數的房東數有多少,轉換爲DT
df2['room_num']=df2.index
df2.reset_index(drop=True,inplace=True)
df2=pd.DataFrame(df2,columns=['room_num','host_id'])
df2.rename(columns={'host_id':'host_num'},inplace=True)
print('以room_num分組:')
df2.head()
df2 = df2.sort_values(by='room_num',ascending=False)
df2.reset_index(drop=True,inplace=True)
df2['room_num_all']=df2['room_num']*df2['host_num']
df2['room_percentage'] = df2['room_num_all'].cumsum()/df2['room_num_all'].sum()*100
df2['host_percentage'] = df2['host_num'].cumsum()/df2['host_num'].sum()*100
df2.tail()
fig = plt.figure(figsize=(8,8))
ax = sns.lineplot(df2.host_percentage,df2.room_percentage)
ax.axvline(x=20,ls="--",c="green")#添加垂直直線
ax.axhline(y=60,ls="--",c="green")#添加垂直直線
ax.set_title(label='房東與房屋數量關係',fontsize=20)
數據分析剛入門,各位巨佬手下留情