房?jī)r(jià)數(shù)據(jù)轉(zhuǎn)換和清洗

1.下載廈門(mén)房?jī)r(jià)信息源文件

下載鏈接:https://pan.baidu.com/s/16D5hw-XBEQnwtsf4fDJ8xw 密碼:e1fg

2.新建一個(gè)ipynb文件

下載成功后,在源文件所在的文件夾中下圖所標(biāo)示的位置中輸入cmd,確定命令正確后運(yùn)行。

打開(kāi)cmd.png

出現(xiàn)的cmd如下圖所示
cmd打開(kāi)后圖示.png

在cmd中輸入命令jypyter notebook
運(yùn)行命令成功圖示.png

新建一個(gè)ipynb文件.png

對(duì)新建的ipynb文件重命名1.png

將ipynb文件重命名為dataProcessing
對(duì)新建的ipynb文件重命名2.png

3.導(dǎo)入數(shù)據(jù)并查看數(shù)據(jù)字段
導(dǎo)入數(shù)據(jù).png

從上圖可以看出原有共15列,分別為:標(biāo)題title、價(jià)格price、首付downPayment、戶(hù)型sizeType、面積size、單價(jià)unitPrice、朝向orientation、樓層floor、裝修decoration、社區(qū)community、區(qū)域region、學(xué)校school、房屋詳情houseDetail、核心賣(mài)點(diǎn)keySellingPoint、配套設(shè)施equipment。

4.數(shù)據(jù)處理

因?yàn)檫@次實(shí)驗(yàn)不用到文本識(shí)別和語(yǔ)義分析,去除標(biāo)題title、核心賣(mài)點(diǎn)keySellingPoint、配套設(shè)置equipment三個(gè)字段。


數(shù)據(jù)處理1.png

在數(shù)據(jù)處理過(guò)程中,需要多次查看DataFrame的字段,所以定義一個(gè)函數(shù)。

def printField(df):
    for x,y in enumerate(list(df.iloc[0].keys()),start=1):
        print(x,y)

觀察數(shù)據(jù)源,發(fā)現(xiàn)首付downPayment字段與價(jià)格price字段成線性關(guān)系,所以要去除這個(gè)字段。

數(shù)據(jù)處理2.png

從事實(shí)的角度出發(fā),因?yàn)槲覀円A(yù)測(cè)房子的房?jī)r(jià),即單價(jià)unitPrice,在不知道單價(jià)的情況下不知道總價(jià),所以刪除總價(jià)price這個(gè)字段。
數(shù)據(jù)處理3.png

現(xiàn)在第一個(gè)字段是sizeType,有一部分行的值為暫無(wú),刪除這個(gè)字段值為暫無(wú)的行。
選出滿(mǎn)足條件的行.png

數(shù)據(jù)處理4.png

從上圖看出DataFrame的行數(shù)從26332行變?yōu)榱?5887行。


把戶(hù)型拆分成3個(gè)字段:室、廳、衛(wèi),以下一段代碼新產(chǎn)生一個(gè)DataFrame保存新產(chǎn)生的3個(gè)字段

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]*)衛(wèi)',sizeType)
    )
    sizeType_list.append(sizeType_dict)
df1 = pd.DataFrame(sizeType_list,columns=sizeType_list[0].keys())

下面的圖把3個(gè)字段賦值給原來(lái)的DataFrame,并顯示一下前面10行

增加3個(gè)字段.png

刪除sizeType字段.png

刪除size字段中的平米,使該字段內(nèi)容變?yōu)閿?shù)字內(nèi)容

處理數(shù)據(jù)6.png


刪除unitPrice字段中的元/平米,使該字段內(nèi)容變?yōu)閿?shù)字內(nèi)容

處理數(shù)據(jù)7.png

將房屋的朝向轉(zhuǎn)換為0-1矩陣,使用pd.get_dummies方法發(fā)現(xiàn)有不規(guī)則值???請(qǐng)選擇朝向

查看是否有異常值.png

查看異常值情況.png

刪除這兩個(gè)異常值


刪除這兩個(gè)異常值.png

處理數(shù)據(jù)8.png

作者發(fā)現(xiàn)后面一些字段的處理相對(duì)來(lái)說(shuō)比較麻煩,所以經(jīng)過(guò)一段時(shí)間的抉擇,統(tǒng)一用函數(shù)產(chǎn)生新的DataFrame,然后把新的DataFrame用pd.concat方法連接起來(lái),這樣編寫(xiě)代碼時(shí)邏輯更清晰。所以前面的篇幅可以用作思路的參考,最終數(shù)據(jù)處理只需要復(fù)制下面一段代碼就可以完成。

'''
原來(lái)的數(shù)據(jù)總共有15列:分別為:標(biāo)題title、價(jià)格price、首付downPayment、
戶(hù)型sizeType、面積size、單價(jià)unitPrice、朝向orientation、樓層floor、
裝修decoration、社區(qū)community、區(qū)域region、學(xué)校school、房屋詳情houseDetail、
核心賣(mài)點(diǎn)keySellingPoint、配套設(shè)施equipment
'''
'''
進(jìn)行簡(jiǎn)單的房?jī)r(jià)預(yù)測(cè)不需要用到文本識(shí)別和語(yǔ)義分析,因此不需要用到title、
keySellingPoint、equipment,根據(jù)現(xiàn)實(shí)的情況來(lái)說(shuō)因?yàn)橄扔袉蝺r(jià)才有總房?jī)r(jià),
而進(jìn)行預(yù)測(cè)的正是單價(jià),所以用不到price、downPayment。觀察房屋詳情,發(fā)現(xiàn)
其中的數(shù)據(jù)有錯(cuò)誤,有的20多層的樓房卻顯示沒(méi)有電梯,這不符合高層住房電梯
規(guī)定,7層及以上住房必須安裝電梯,不符合實(shí)際,所有房產(chǎn)有無(wú)電梯根據(jù)總樓層數(shù)判斷
'''
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]*)衛(wèi)',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("廈門(mén)房?jī)r(jià)數(shù)據(jù)(房天下版).xlsx")
    df = cleanCommunity(df)
    df = cleanFloor(df)
    df = cleanSizeType(df)
    #下面幾個(gè)字段是列數(shù)較少的字段
    unitPrice = getUnitPrice(df)
    sizeType = getSizeType(df)
    elevator = getElevator(df)
    community = getCommunity(df)
    school = getSchool(df)
    #下面的字段是通過(guò)get_dummies方法產(chǎn)生的9-1矩陣,列數(shù)較多
    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("數(shù)據(jù)處理結(jié)果.xlsx",columns = df_new.iloc[0].keys())
    print("數(shù)據(jù)處理共花費(fèi)%.2f秒" %(time.time()-startTime))    
數(shù)據(jù)處理結(jié)果圖示.png
最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時(shí)請(qǐng)結(jié)合常識(shí)與多方信息審慎甄別。
平臺(tái)聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡(jiǎn)書(shū)系信息發(fā)布平臺(tái),僅提供信息存儲(chǔ)服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

友情鏈接更多精彩內(nèi)容