Python数据分析实战之一--某网站二手房交易信息(数据处理)
程序员文章站
2022-03-29 08:12:30
...
根据链家网二手房交易信息对二手房交易数据进行分析
用到的数据包含147169条交易信息,每条交易信息包括["房型","成交时间","地址","价格","朝向","装修","建造年代","楼层","产权","面积","得房面积","有无钥匙","编号"]列信息。
1. 首先载入数据集
此处用到的数据集为excel,可以使用pandas的pd.read_excel("data.xlsx", 0, header=None)
加载当前目录下excel文件"data.xlsx"的第1页(excel内包含多个sheet时,选择某页加载),并且没有列标签。
# 加载模块
import pandas as pd
import seaborn as sns
import matplotlib.pyplot as plt
%matplotlib inline
# 让中文和负号在图表中正常显示
plt.rcParams['font.sans-serif']=['SimHei'] #用来正常显示中文标签
plt.rcParams['axes.unicode_minus']=False #用来正常显示负号
# 加载数据集
df = pd.read_excel("bjlianjia.xlsx",0,header=None) # 0表示excel的sheet1
# 添加列名
df.columns = ["房型","成交时间","地址","价格","朝向","装修","建造年代","楼层","产权","面积","得房面积","有无钥匙","编号"]
2. 数据处理
df.dtypes可以得到各特征的数据类型,只有价格为float64,其他特征均为object。这种字符型数据不适合进行数据分析,需处理为可以分析比较的数值型数据。
写代码的时候一定要有异常捕获机制,使用try/except/else/finally来应对数据格式不符合规范时报错。
对"房型"数据进行处理:
# 定义函数逐行处理“房型”数据
def _parsehouse(s):
# 使用try/except语句避免出现Error终止程序
try:
s = s.strip()
r=[]
if len(s)==8:
r.append(s[0])
r.append(s[2])
r.append(s[4])
r.append(s[6])
else:
r=[-1,-1,-1,-1]
except:
r=[-1,-1,-1,-1]
return r
df_room = pd.DataFrame(df["房型"].apply(lambda s: _parsehouse(s)).values.tolist(),
columns = ["室","厅","厨","卫"])
# df["房型"].apply(lambda s: _parsehouse(s))得到的是一个Series(pandas一维数据),每行为[2,1,1,1]这种类型
# .values将Series转换成Array(numpy一维array),array(list[2,1,1,1],list[...],...)
# .tolist()将array转换成list,[['2','1','1','1'],['3','1','1','1'],...]
# 在外面使用df.DataFrame将list转换成pandas 二维DataFrame格式
# 因为数据集中还存在“-室-厅-厨-卫”的数据,使用replace替换一下
df_room.replace({'-':'-1'},inplace=True)
对“成交时间”进行提取:
# 因为成交时间包括时间(年月日,空格,成交平台),可以用正则表达式来提取年月日
import re
def _parsedate(s):
try:
# 因为在原文本中年月日格式为2017.07.08,故可以用正则表达式“[\d\.]+”,
# \d匹配任何十进制数字,\.匹配字符“.”,[]+匹配方括号里任意组合一次或多次
data = re.compile("[\d\.]+")
return data.findall(s)[0]
except:
return -1.-1.-1
# 先将年月日提取出来,组成一个Series
df_date1=df["成交时间"].apply(lambda s:_parsedate(s))
# 再逐列2017.07.06提取年月日
df_date = pd.DataFrame(df_date1.apply(lambda s:str(s).split(".")).values.tolist(),columns = ["年","月","日"])
df_date.fillna(-1,inplace=True)
# 在提取过程中s.split(".")会报错”'float' object has no attribute 'split' “
# 因为存在2017.07,系统将其错认为'float'
# 因此需要使用str(s),将所有行转换成字符形式
对"朝向"数据进行处理:
def _parseCX(s):
try:
s=s.strip()
return s.split(" ")
except:
return ["unknown"]
df_CX = pd.DataFrame(df['朝向'].apply(lambda s: _parseCX(s)).values.tolist())
对“面积”和“产权”进行处理:
def _parsenumber(s):
try:
data = re.compile("[\d\.]+")
return data.findall(s)[0]
except:
return -1
df_area = pd.DataFrame(df["面积"].apply(lambda s: _parsenumber(s)).values.tolist(), columns=["面积"])
df_property = pd.DataFrame(df["产权"].apply(lambda s: _parsenumber(s)).values.tolist(), columns=["产权"])
对“价格”和“建造年代”的NaN值进行填充:
# 将价格未知填充为0
df["价格"].fillna(0, inplace=True)
# 将建造年代未知填充为-1
df["建造年代"].fillna(-1, inplace=True)