日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程资源 > 编程问答 >内容正文

编程问答

在售房源数据可视化

發(fā)布時間:2024/3/24 编程问答 21 豆豆
生活随笔 收集整理的這篇文章主要介紹了 在售房源数据可视化 小編覺得挺不錯的,現(xiàn)在分享給大家,幫大家做個參考.

項目要求

探索地理位置、單價、面積、房屋朝向、戶型、樓層位置等因素對購房者關注熱度的影響。

數(shù)據(jù)讀取

讀取CSV文件,瀏覽各字段內(nèi)容

補充 ① :

忽略警告
import warnings
warnings.filterwarnings(‘ignore’)

import pandas as pd data=pd.read_csv(r"C:\Users\TP\Desktop\在售房源數(shù)據(jù)可視化\數(shù)據(jù)\house.csv") #或者寫成 data=pd.read_csv("C:/Users/TP/Desktop/在售房源數(shù)據(jù)可視化/數(shù)據(jù)/house.csv") # 但是將斜杠/ 一個個改為反斜杠\ 太麻煩了data.head() 產(chǎn)權關注區(qū)域單價小區(qū)年限總價/萬元戶型房屋編碼掛牌時間朝向樓層裝修情況面積01234
70年0余杭臨平21015元/平米眾安理想灣2015年建/板樓210.03室2廳1031050130262019-06-12南 北低樓層/共33層平層/精裝99.93平米
70年4余杭臨平28416元/平米眾安理想灣2016年建/板塔結合780.06室2廳1031043249062019-04-04聯(lián)排/共3層毛坯274.5平米
70年2余杭臨平17323元/平米眾安理想灣2015年建/板樓220.03室2廳1031028551202018-09-07高樓層/共33層精裝127平米
70年4余杭臨平18249元/平米眾安理想灣2015年建/塔樓250.03室2廳1031027371212018-08-15中樓層/共33層簡裝137平米
70年1余杭臨平24112元/平米眾安理想灣2015年建/板樓215.03室2廳1031044981622019-04-21高樓層/共34層精裝89.17平米

補充②

d=data[“單價”].apply(lambda x: str(x)).str.findall("(\d+)").str[0].astype(“float”);

Series.str.findall() 與re模塊findall 類似

str[0] 妙用如下:

補充③:

data[“起建時間”]=data[“年限”].str.split("/").str[0]
data[“建筑類型”]=data[“年限”].str.split("/").str[1]

data=data[(data[“起建時間”]!=“未知年建”) & (data[“建筑類型”] != “暫無數(shù)據(jù)”)]

補充④:

data[“面積”].apply(lambda x: str(x)).str.extract("([\d,.]+)")

正則表達式"([\d,.]+)" 中方括號[]中的 點和逗號均代表“點和逗號”自身,無拓展意思。而且用str模塊extract或者findall處理時需要保證數(shù)據(jù)為字符串格式,否則會結果會出現(xiàn)錯誤。如下:

數(shù)據(jù)清洗

df=data.copy() df.dropna(inplace=True) #刪除空值 a=df[df.duplicated(keep=False)] #print("重復數(shù)據(jù):",a) df.drop_duplicates(inplace=True,ignore_index=True) # 刪除重復數(shù)據(jù),ignore_index=True 重置索引 print(df.info()) <class 'pandas.core.frame.DataFrame'>RangeIndex: 30765 entries, 0 to 30764Data columns (total 14 columns):# Column Non-Null Count Dtype --- ------ -------------- ----- 0 產(chǎn)權 30765 non-null object 1 關注 30765 non-null int64 2 區(qū)域 30765 non-null object 3 單價 30765 non-null object 4 小區(qū) 30765 non-null object 5 年限 30765 non-null object 6 總價/萬元 30765 non-null float647 戶型 30765 non-null object 8 房屋編碼 30765 non-null int64 9 掛牌時間 30765 non-null object 10 朝向 30765 non-null object 11 樓層 30765 non-null object 12 裝修情況 30765 non-null object 13 面積 30765 non-null object dtypes: float64(1), int64(2), object(11)memory usage: 3.3+ MBNone```python```python data1=df.copy() data1.head() 產(chǎn)權關注區(qū)域單價小區(qū)年限總價/萬元戶型房屋編碼掛牌時間朝向樓層裝修情況面積01234
70年0余杭臨平21015元/平米眾安理想灣2015年建/板樓210.03室2廳1031050130262019-06-12南 北低樓層/共33層平層/精裝99.93平米
70年4余杭臨平28416元/平米眾安理想灣2016年建/板塔結合780.06室2廳1031043249062019-04-04聯(lián)排/共3層毛坯274.5平米
70年2余杭臨平17323元/平米眾安理想灣2015年建/板樓220.03室2廳1031028551202018-09-07高樓層/共33層精裝127平米
70年4余杭臨平18249元/平米眾安理想灣2015年建/塔樓250.03室2廳1031027371212018-08-15中樓層/共33層簡裝137平米
70年1余杭臨平24112元/平米眾安理想灣2015年建/板樓215.03室2廳1031044981622019-04-21高樓層/共34層精裝89.17平米

各字段瀏覽

瀏覽個字段信息格式,是否需要做進一步處理,比如取數(shù)值或者取特定意義的字段

產(chǎn)權

# 各字段唯一值瀏覽:產(chǎn)權 df.產(chǎn)權.unique() # 產(chǎn)權 字段 # 計算產(chǎn)權“未知”的數(shù)量 df.groupby("產(chǎn)權").size() df[df.產(chǎn)權=="未知"] #查看產(chǎn)權“未知”數(shù)據(jù)是否需要做特殊處理,比如刪除、0值填充

初步考慮產(chǎn)權“未知”行只有7行,占比總體數(shù)據(jù)比率較少。但是這部分數(shù)據(jù)的其他字段并無異常,暫時不做刪除或者量化處理

區(qū)域

地域分區(qū):上城,下城,臨安,余杭,富陽,拱墅,江干,濱江,蕭山,西湖,錢塘新區(qū)

# 函數(shù)定義,區(qū)域分區(qū),例如:西湖文三西路,改為西湖;區(qū)域:上城,下城,臨安,余杭,富陽,拱墅,江干,濱江,蕭山,西湖,錢塘新區(qū) import re def qy(data):if re.match("上城",data):return "上城"elif re.match("下城",data):return "下城"elif re.match("臨安",data):return "臨安"elif re.match("余杭",data):return "余杭"elif re.match("富陽",data):return "富陽"elif re.match("拱墅",data):return "拱墅"elif re.match("江干",data):return "江干"elif re.match("濱江",data):return "濱江"elif re.match("蕭山",data):return "蕭山"elif re.match("西湖",data):return "西湖"elif re.match("錢塘新區(qū)",data):return "錢塘新區(qū)" a=df.copy() df["地區(qū)"]=a.區(qū)域.apply(qy) b=df.drop(columns="區(qū)域") data2=b.copy() df=data2.copy()

單價

# 提取"單價"中的數(shù)字 def dj(x):b=re.match("\d+",x).group()return b # 或者以下 def dj1(x):b=re.findall(r"\b(\d+)元/平米\b",x)[0]return b # 注意findall 與 match 的區(qū)別 findall 返回的是list match 返回的是string data2["單價dj"]=df.單價.apply(dj1) data2.drop(columns="單價",inplace=True) data2.rename(columns={"單價dj":"單價","地區(qū)":"區(qū)域"},inplace=True) df=data2.copy() df.drop(columns="小區(qū)",inplace=True) data2=df.copy()

年限

# 定義函數(shù),提取年限中的有效字段,如果是“未知年限”則提取“未知” def nx(x):b=re.match(r"(.+)年建.+",x).group(1)return b # 刪除部分字段 ,提取年限中的有限字段 data3=data2.copy() data3["nx"]=data2.年限.apply(nx) data3.drop(columns=["年限","戶型","房屋編碼"],inplace=True) data3.rename(columns={"nx":"年限"},inplace=True) df=data3.copy()

朝向

# 定于朝向函數(shù),假定數(shù)據(jù)朝向列中的第一個空格前為房屋朝向,例如“東 南 北 東北” 的朝向定義為“東” def cx(x):a=re.findall(r"\b.+?\b",x)[0]return a data4=data3.copy() data4["cx"]=df.朝向.apply(cx) data4.drop(columns="朝向",inplace=True) data4.rename(columns={"cx":"朝向"},inplace=True) df=data4.copy()

樓層

# 函數(shù)定義 def lc(x):z=[]if re.match("(.+?)/.*?(\d+).*",x):z.append(re.match("(.+?)/.*?(\d+).*",x).group(1)) # 注意 () 的應用,以及(\d+)前的*?,即最小匹配。如果是采用貪婪匹配會與預期值有出入z.append(re.match("(.+?)/.*?(\d+).*",x).group(2))elif re.match(".*?(\d+).*",x):z=["未知",re.match(".*?(\d+).*",x).group(1)] # 共3層 對于類似情況,只提取樓高 3else:z=["未知","未知"]return z import numpy as np a=df.樓層.apply(lc).to_list() a=np.array(a) data5=data4.copy() data5["Lc"]=a[:,0] data5["Lg"]=a[:,1] data5.drop(columns="樓層",inplace=True) data5.rename(columns={"Lc":"樓層","Lg":"樓高"},inplace=True)

裝修情況

data6=data5.copy() data6["zsqk"]=data5.裝修情況.apply(lambda x : x[-2:]) data6.drop(columns="裝修情況",inplace=True) data6.rename(columns={"zsqk":"裝修情況"},inplace=True)

掛牌時間

import pandas as pd df=data6.copy() data7=data6.copy() data7["掛牌時間"]=pd.to_datetime(data6.掛牌時間)

面積

# 面積數(shù)據(jù)提取函數(shù)定義 def mj(x):d=re.match("\d+",x).group()return d df=data7.copy() data8=data7.copy() data8["面積"]=data7.面積.apply(mj) df=data8.copy()

字符轉換成數(shù)值

# 定義數(shù)值轉換函數(shù),如果字符可以轉換成數(shù)值則執(zhí)行轉換,如果字符不可以轉換成字符則返回原字符 # 方法一: def zh(x):try:float(x)except:return xelse :return int(x) # 方法二:如果是 a=pd.Series(["1","2","3","abc"]) 這種情況下以下定義函數(shù)有效,如果是b=pd.Series(["1.0","2.0","3.0","abc"]) 情況以下函數(shù)失效; def zh1(x):if x.isdigit():return float(x)else:return x df=data8.copy() data9=data8.copy() data9[["總價/萬元","面積","單價","樓高"]]=df[["總價/萬元","面積","單價","樓高"]].applymap(zh) data9.info() <class 'pandas.core.frame.DataFrame'> RangeIndex: 30765 entries, 0 to 30764 Data columns (total 12 columns):# Column Non-Null Count Dtype --- ------ -------------- ----- 0 產(chǎn)權 30765 non-null object 1 關注 30765 non-null int64 2 總價/萬元 30765 non-null float64 3 掛牌時間 30765 non-null datetime64[ns]4 面積 30765 non-null float64 5 區(qū)域 30765 non-null object 6 單價 30765 non-null float64 7 年限 30765 non-null object 8 朝向 30765 non-null object 9 樓層 30765 non-null object 10 樓高 30765 non-null object 11 裝修情況 30765 non-null object dtypes: datetime64[ns](1), float64(3), int64(1), object(7) memory usage: 2.8+ MB

字段相關性

字段標準化

測試標準化是否影響相關系數(shù),初步猜測不影響 # 總價與關注度 zj=df.groupby("總價/萬元").關注.sum() zj=zj.reset_index() zj.corr() 總價/萬元關注總價/萬元關注
1.000000-0.171617
-0.1716171.000000
# 數(shù)據(jù)標準化,測試數(shù)據(jù)標準化是否會影響數(shù)據(jù)之間的關系系數(shù) cs=zj.copy() cs["pr"]=(zj["總價/萬元"]-zj["總價/萬元"].mean())/zj["總價/萬元"].std() cs["gz"]=(zj["關注"]-zj["關注"].mean())/zj["關注"].std()

補充⑤:

通過熱力圖可以更直接的表示各個因素之間的相關程度

corr=df.corr() plt.figure(figsize=(8, 6)) sns.heatmap(corr, cmap='GnBu') plt.show()

數(shù)據(jù)之間的關系系數(shù)

cs.corr() 總價/萬元關注prgz總價/萬元關注prgz
1.000000-0.1716171.000000-0.171617
-0.1716171.000000-0.1716171.000000
1.000000-0.1716171.000000-0.171617
-0.1716171.000000-0.1716171.000000

注意:數(shù)據(jù)標準化并不影響數(shù)據(jù)之間的關系系數(shù)

df.corr() 關注總價/萬元面積單價關注總價/萬元面積單價
1.000000-0.014854-0.0479610.018297
-0.0148541.0000000.7363370.557916
-0.0479610.7363371.000000-0.016588
0.0182970.557916-0.0165881.000000

可視化

分別用pandas、seaborn、pyecharts可視化

產(chǎn)權可視化

# 根據(jù)產(chǎn)權分組計算關注度,將結果可視化 print(df.產(chǎn)權.unique()) cq=df.groupby("產(chǎn)權")["關注"].sum() cq=pd.DataFrame(cq) # 刪除產(chǎn)權不明的數(shù)據(jù) cq=cq[cq.index != "未知"]

pandas 可視化

# pandas 庫 plot.bar 可視化 import pandas as pd import matplotlib.pyplot as plt import numpy as npplt.rcParams["font.sans-serif"]=["SimHei"] # 解決中文顯示異常 plt.rcParams["axes.unicode_minus"]=False # 負號正常顯示cq.plot(kind="bar",rot=40,figsize=(10,6)) #繪制柱狀圖 # 添加數(shù)據(jù)標簽 for x ,y in zip(np.arange(len(cq)),cq["關注"].tolist()):plt.text(x,y+10000,y)

seaborn 可視化

# seaborn 庫可視化 import seaborn as sns import matplotlib.pyplot as plt plt.rcParams["font.sans-serif"]=["SimHei"] # 解決中文亂碼,注意如果設置seaborn style 則需要在 set_style 中設置中文顯示亂碼問題,此設置失效 plt.rcParams['axes.unicode_minus'] = False # 負號正常顯示sns.set_style("whitegrid",{'font.sans-serif':['simhei','Arial']}) #圖表風格 plt.figure(figsize=(10,6)) x=cq.index y=cq.關注 ax=sns.barplot(x,y) ax.set_xticklabels(x,rotation=45) # 添加數(shù)據(jù)標簽 for x ,y in zip(np.arange(len(cq)),cq["關注"].tolist()):plt.text(x,y+10000,y)

pyecharts

from pyecharts.charts import Bar from pyecharts.globals import ThemeType from pyecharts import options as optsfrom pyecharts.globals import WarningType WarningType.ShowWarning = False # 刪除可惡的警報x=cq.index.to_list() y=cq.關注.to_list() bar=(Bar(init_opts=opts.InitOpts(theme=ThemeType.DARK,width="800px",height="500px")).add_xaxis(x).add_yaxis("關注度",y,bar_width=80)) bar.render_notebook()

總價與關注度

zj=df[["關注","總價/萬元"]].sort_values(by="總價/萬元",ascending=True) zj.head() 關注總價/萬元119315203261232614215213
5629.8
5935.0
436.0
338.0
1939.0

利用Kmeans 將總價分層

Kmeans K值確定

利用肘部法則和輪廓系數(shù)法確定Kmeans中的K值

df.info() <class 'pandas.core.frame.DataFrame'> Int64Index: 30765 entries, 0 to 30764 Data columns (total 12 columns):# Column Non-Null Count Dtype --- ------ -------------- ----- 0 產(chǎn)權 30765 non-null object 1 關注 30765 non-null int64 2 總價/萬元 30765 non-null float64 3 掛牌時間 30765 non-null datetime64[ns]4 面積 30765 non-null int64 5 區(qū)域 30765 non-null object 6 單價 30765 non-null int64 7 年限 30765 non-null object 8 朝向 30765 non-null object 9 樓層 30765 non-null object 10 樓高 30765 non-null object 11 裝修情況 30765 non-null object dtypes: datetime64[ns](1), float64(1), int64(3), object(7) memory usage: 4.3+ MB import numpy as np from sklearn.cluster import KMeans import matplotlib.pyplot as plt from sklearn import metrics # SSE K = range(2, 31) SSE = [] # SSE 記錄平方距離和 silhouette_scores=[] # 記錄各個K值的輪廓系數(shù) silhouette_score X=np.array(df["總價/萬元"].to_list()).reshape(-1, 1) #為使用sihouette計算輪廓系數(shù),構建縱坐標為0的二維數(shù)組 y=np.zeros((len(X),1)) z=np.array(list(zip(X,y))).reshape(-1,2) for k in K:kmeanModel = KMeans(n_clusters=k).fit(z)SSE.append(kmeanModel.inertia_)silhouette_scores.append(metrics.silhouette_score(z,kmeanModel.labels_,metric='euclidean'))# SSE 肘部法則 plt.figure(figsize=(10,6)) plt.subplot(2,1,1) plt.plot(K, SSE, 'bx-') plt.xlabel('k') plt.ylabel('SSE') plt.title('SSE 肘部法則')# 輪廓系數(shù) silhouette_scores 特別消耗計算機,運行比較慢 plt.subplot(2,1,2) plt.plot(K,silhouette_scores) plt.xlabel("K") plt.ylabel("silhouette_scores") plt.title('輪廓系數(shù)') plt.show()# 根據(jù)肘部法則能夠確認最佳K 值為 5

分組

K值確定后,用Kmeans 模型對“總價”進行分組總計關注度

# 使用Kmeans K=5 將“總價/萬元”分組 X=np.array(df["總價/萬元"].to_list()).reshape(-1, 1) kmeanModel = KMeans(n_clusters=5).fit(X) labels=pd.Series(kmeanModel.labels_,index=df.index) df_k=pd.concat([df[["總價/萬元","關注"]],labels],axis=1) df_k.columns=["總價/萬元","關注","分類"] df1=df_k.groupby(by="分類").agg({"總價/萬元":["mean","min","max","count"],"關注":["sum"]}) df1.columns=["均值","總價_min","總價_max","計數(shù)","關注"] df1["分組"]=df1["總價_min"].astype(str)+" - "+df1["總價_max"].astype(str) zj=df1[["分組","關注"]] zj

總價可視化

pandas 可視化

z=zj.plot.bar(figsize=(10,6),y="關注",x="分組",rot=45,title="總價與關注度") for i in np.arange(5):plt.text(i,zj["關注"][i]+5000,zj["關注"][i])

seaborn 可視化

# seaborn 庫可視化 import seaborn as sns import matplotlib.pyplot as plt plt.rcParams["font.sans-serif"]=["SimHei"] # 解決中文亂碼,注意如果設置seaborn style 則需要在 set_style 中設置中文顯示亂碼問題,此設置失效 plt.rcParams['axes.unicode_minus'] = False # 負號正常顯示sns.set_style("darkgrid",{'font.sans-serif':['simhei','Arial']}) #圖表風格 plt.figure(figsize=(10,6)) x=zj.分組 y=zj.關注 ax=sns.barplot(x,y) ax.set_xticklabels(x,rotation=45) # 添加數(shù)據(jù)標簽 for x ,y in zip(np.arange(len(zj)),zj["關注"].tolist()):plt.text(x,y+5000,y)

pyecharts 可視化

from pyecharts.charts import Bar from pyecharts.globals import ThemeType from pyecharts import options as optsimport numpy as np x=zj.分組.tolist() y=zj.關注.tolist() bar=(Bar(init_opts=opts.InitOpts(theme=ThemeType.MACARONS,width="1000px",height="600px")).add_xaxis(x).add_yaxis("關注度",y,bar_max_width=60)) bar.render_notebook()

面積與關注度

mj=df.groupby("面積").關注.sum().reset_index() mj

pandas 可視化

x=mj.面積.to_list() y=mj.關注.to_list()mj_max=mj[mj.關注==max(mj.關注)] x_max=mj_max.iloc[0,1] y_max=mj_max.iloc[0,0]mj.plot.line(figsize=(10,6),x="面積",y="關注",title="面積與關注度") plt.text(y_max,x_max-2000,("面積:"+str(y_max)+"\n"+"關注度:"+str(x_max)),fontsize=14)

seaborn 可視化

# seaborn 庫可視化 import seaborn as sns import matplotlib.pyplot as pltsns.set_style("dark",{'font.sans-serif':['simhei','Arial']}) #圖表風格,如果不設置san-serif中文會顯示異常 plt.figure(figsize=(10,6))x=mj.面積.to_list() y=mj.關注.to_list()mj_max=mj[mj.關注==max(mj.關注)] x_max=mj_max.iloc[0,1] y_max=mj_max.iloc[0,0]ax=sns.lineplot(x,y)plt.text(y_max,x_max-2000,("面積:"+str(y_max)+"\n"+"關注度:"+str(x_max)),fontsize=14) #對最大值添加數(shù)字標簽

pyecharts 可視化

from pyecharts.charts import Line from pyecharts.globals import ThemeType from pyecharts import options as opts import numpy as npx=mj.面積.to_list() y=mj.關注.to_list()line=(Line(init_opts=opts.InitOpts(theme=ThemeType.CHALK)).add_xaxis(x).add_yaxis("關注度",y)) line.render_notebook()

補充⑥:

#關于區(qū)域性質(zhì)的數(shù)據(jù),用地區(qū)顯示很直觀pair1 = [(row["地理位置"], row['關注']) for i, row in count_area.iterrows()]map1=Map(init_opts=opts.InitOpts(theme='macarons',width = '800px', height='400px'))map1.add('杭州',pair1,"杭州",is_roam=False)map1.set_series_opts(label_opts=opts.LabelOpts(is_show=False))map1.set_global_opts(title_opts=opts.TitleOpts(title="杭州市各區(qū)房源數(shù)量對比"),legend_opts=opts.LegendOpts(is_show=True),visualmap_opts=opts.VisualMapOpts(min_=count_area["關注"].min(), max_=count_area["關注"].max()))map1.render_notebook()

其它因素可視化

單價同前面總價處理流程;
年限、朝向、樓層、裝修情況、樓高與前面的柱狀圖\條形圖 處理方式相似 不再一一贅述;
可以考慮創(chuàng)建一個函數(shù)或者類,直接傳入?yún)?shù)得到自己想要的圖表;
以下定義了一個簡單的函數(shù),直接調(diào)用函數(shù)傳入相應的參數(shù)即可直接顯示該因素與關注度的可視化圖表;

def charts(label="區(qū)域"): # 通過指定label的值,可視化數(shù)據(jù)圖表import seaborn as sns import numpy as npqy=df.groupby(by=label).關注.sum().reset_index()x=qy[label].to_list()y=qy["關注"].to_list()qy.plot.bar(x=label,y="關注",figsize=(12,8),rot=45,title="區(qū)域與關注度")for i,j in zip(np.arange(len(x)),y):plt.text(i,j+2000,j,horizontalalignment="center")qy_sort=qy.sort_values(by="關注",ascending=False)x=qy_sort[label].to_list()y=qy_sort["關注"].to_list()plt.figure(figsize=(12,8))sns.barplot(y,x,orient="h")for i,j in zip(np.arange(len(x)),y):plt.text(j,i,j,horizontalalignment="left") # 朝向與關注度可視化 charts("朝向")


總結

以上是生活随笔為你收集整理的在售房源数据可视化的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網(wǎng)站內(nèi)容還不錯,歡迎將生活随笔推薦給好友。