1.下載廈門房價信息源文件
下載鏈接:https://pan.baidu.com/s/16D5hw-XBEQnwtsf4fDJ8xw 密碼:e1fg
2.新建一個ipynb文件
下載成功后,在源文件所在的文件夾中下圖所標示的位置中輸入cmd,確定命令正確后運行。
打開cmd.png
出現的cmd如下圖所示
cmd打開后圖示.png
在cmd中輸入命令jypyter notebook
運行命令成功圖示.png
新建一個ipynb文件.png
對新建的ipynb文件重命名1.png
將ipynb文件重命名為dataProcessing
對新建的ipynb文件重命名2.png
3.導入數據并查看數據字段
導入數據.png
從上圖可以看出原有共15列,分別為:標題title、價格price、首付downPayment、戶型sizeType、面積size、單價unitPrice、朝向orientation、樓層floor、裝修decoration、社區community、區域region、學校school、房屋詳情houseDetail、核心賣點keySellingPoint、配套設施equipment。
4.數據處理
因為這次實驗不用到文本識別和語義分析,去除標題title、核心賣點keySellingPoint、配套設置equipment三個字段。
數據處理1.png
在數據處理過程中,需要多次查看DataFrame的字段,所以定義一個函數。
def printField(df):
for x,y in enumerate(list(df.iloc[0].keys()),start=1):
print(x,y)
觀察數據源,發現首付downPayment字段與價格price字段成線性關系,所以要去除這個字段。
數據處理2.png
從事實的角度出發,因為我們要預測房子的房價,即單價unitPrice,在不知道單價的情況下不知道總價,所以刪除總價price這個字段。
數據處理3.png
現在第一個字段是sizeType,有一部分行的值為暫無,刪除這個字段值為暫無的行。
選出滿足條件的行.png
數據處理4.png
從上圖看出DataFrame的行數從26332行變為了25887行。
把戶型拆分成3個字段:室、廳、衛,以下一段代碼新產生一個DataFrame保存新產生的3個字段
import pandas as pd
import re
sizeType_list = []
def findNumber(reStr,sourceStr):
result_list = re.findall(reStr,sourceStr)
if len(result_list):
return result_list[0]
else:
return 0
for i in range(len(df)):
sizeType = df['sizeType'].iloc[i]
sizeType_dict = dict(
room = findNumber('([0-9]*)室',sizeType),
hall = findNumber('([0-9]*)廳',sizeType),
restroom =findNumber('([0-9]*)衛',sizeType)
)
sizeType_list.append(sizeType_dict)
df1 = pd.DataFrame(sizeType_list,columns=sizeType_list[0].keys())
下面的圖把3個字段賦值給原來的DataFrame,并顯示一下前面10行
增加3個字段.png
刪除sizeType字段.png
刪除size字段中的平米,使該字段內容變為數字內容
處理數據6.png
刪除unitPrice字段中的元/平米,使該字段內容變為數字內容
處理數據7.png
將房屋的朝向轉換為0-1矩陣,使用pd.get_dummies方法發現有不規則值???和請選擇朝向。
查看是否有異常值.png
查看異常值情況.png
刪除這兩個異常值
刪除這兩個異常值.png
處理數據8.png
作者發現后面一些字段的處理相對來說比較麻煩,所以經過一段時間的抉擇,統一用函數產生新的DataFrame,然后把新的DataFrame用pd.concat方法連接起來,這樣編寫代碼時邏輯更清晰。所以前面的篇幅可以用作思路的參考,最終數據處理只需要復制下面一段代碼就可以完成。
'''
原來的數據總共有15列:分別為:標題title、價格price、首付downPayment、
戶型sizeType、面積size、單價unitPrice、朝向orientation、樓層floor、
裝修decoration、社區community、區域region、學校school、房屋詳情houseDetail、
核心賣點keySellingPoint、配套設施equipment
'''
'''
進行簡單的房價預測不需要用到文本識別和語義分析,因此不需要用到title、
keySellingPoint、equipment,根據現實的情況來說因為先有單價才有總房價,
而進行預測的正是單價,所以用不到price、downPayment。觀察房屋詳情,發現
其中的數據有錯誤,有的20多層的樓房卻顯示沒有電梯,這不符合高層住房電梯
規定,7層及以上住房必須安裝電梯,不符合實際,所有房產有無電梯根據總樓層數判斷
'''
import pandas as pd
import re
import time
def getSizeType(df):
def findNumber(reStr,sourceStr):
result_list = re.findall(reStr,sourceStr)
if len(result_list):
return result_list[0]
else:
return 0
sizeType_list = []
for i in range(len(df)):
sizeType = df['sizeType'].iloc[i]
sizeType_dict = dict(
room = findNumber('([0-9]*)室',sizeType),
hall = findNumber('([0-9]*)廳',sizeType),
restroom =findNumber('([0-9]*)衛',sizeType)
)
sizeType_list.append(sizeType_dict)
return pd.DataFrame(sizeType_list,columns=sizeType_list[0].keys())
def getSize(df):
df1 = df['size'].copy()
for i in range(len(df)):
size = float(df['size'].iloc[i].strip("平米"))
if size < 50:
df1.iloc[i] = 'size1'
elif size < 100:
df1.iloc[i] = 'size2'
elif size < 150:
df1.iloc[i] = 'size3'
elif size < 200:
df1.iloc[i] = 'size4'
else:
df1.iloc[i] = 'size5'
return pd.get_dummies(df1)
def getUnitPrice(df):
df1 = df['unitPrice'].copy()
for i in range(len(df)):
df1.iloc[i] = df['unitPrice'].iloc[i].strip("元/平米")
return df1
def getOrientation(df):
return pd.get_dummies(df['orientation'])
def getHeight(df):
df1 = df['floor'].copy()
for i in range(len(df)):
df1.iloc[i] = df['floor'].iloc[i].split(' ')[0][0]
return pd.get_dummies(df1)
def getElevator(df):
ele_list = []
for i in range(len(df)):
str1 = df['floor'].iloc[i].split(' ')[1]
allFloor = int(re.findall("共(.*)層",str1)[0])
elevator = 1 if allFloor >= 8 else 0
ele_dict = {'elevator':elevator}
ele_list.append(ele_dict)
df1 = pd.DataFrame(ele_list)
return df1
def getDecoration(df):
df1 = df['decoration'].copy()
for i in range(len(df)):
df1.iloc[i] = df['decoration'].iloc[i].strip('修')
return pd.get_dummies(df1)
def getCommunity(df):
df1 = df['community'].copy()
for i in range(len(df)):
df1.iloc[i] = 1 if df['community'].iloc[i] == \
df['community'].iloc[i] else 0
return df1
def getDistrict(df):
df1 = df['region'].copy()
for i in range(len(df)):
df1.iloc[i] = df['region'].iloc[i].split('-')[0]
return pd.get_dummies(df1)
def getRegion(df):
df1 = df['region'].copy()
for i in range(len(df)):
region = df['region'].iloc[i].split('-')[1]
df1.iloc[i] = region.strip('(').strip(')')
return pd.get_dummies(df1)
def getSchool(df):
df1 = df['school'].copy()
for i in range(len(df)):
df1.iloc[i] = 1 if df['region'].iloc[i] == \
df['region'].iloc[i] else 0
return df1
def cleanFloor(df):
for i in range(len(df)):
if '共' not in df['floor'].loc[i]:
df = df.drop([i])
df = df.reset_index(drop=True)
return df
def cleanSizeType(df):
for i in range(len(df)):
if '室' not in df['sizeType'].loc[i]:
df = df.drop([i])
df = df.reset_index(drop=True)
return df
def cleanCommunity(df):
df = df[df['community'] == df['community']]
df = df.reset_index(drop=True)
return df
if __name__ == "__main__":
startTime = time.time()
df = pd.read_excel("廈門房價數據(房天下版).xlsx")
df = cleanCommunity(df)
df = cleanFloor(df)
df = cleanSizeType(df)
#下面幾個字段是列數較少的字段
unitPrice = getUnitPrice(df)
sizeType = getSizeType(df)
elevator = getElevator(df)
community = getCommunity(df)
school = getSchool(df)
#下面的字段是通過get_dummies方法產生的9-1矩陣,列數較多
orientaion = getOrientation(df)
height = getHeight(df)
size = getSize(df)
decoration = getDecoration(df)
district = getDistrict(df)
region = getRegion(df)
df_new = pd.concat([unitPrice,sizeType,elevator,community,school,\
orientaion,height,size,decoration,district,region],\
axis=1)
df_new.to_excel("數據處理結果.xlsx",columns = df_new.iloc[0].keys())
print("數據處理共花費%.2f秒" %(time.time()-startTime))
數據處理結果圖示.png