租房数据-数据分析

文章目录

    • 租房数据分析
      • 一、 读取数据,并简单处理数据
        • 1.1 判断是否有重复值
        • 1.2 判断是否有缺失值
      • 二、简单分析数据
        • 2.1 处理数据
        • 2.2 查看价格、面积的分布情况
          • 价格的分布情况
          • 面积的分布情况
        • 2.3 区域、层数对价格的影响
          • 各个区域的价格分布情况
          • 各个层级的价格分布情况
      • 三、分析数据间的相关性
      • 四、数据标准化
      • 五、总结


租房数据分析


先导入相关的数据处理库
import numpy as np
import pandas as pd

import matplotlib.pyplot as plt
import seaborn as sns
import warnings
warnings.filterwarnings('ignore')
%matplotlib inline

一、 读取数据,并简单处理数据

df = pd.read_csv("租房信息.csv")
df.head()



1.1 判断是否有重复值

len(df["标题"].unique()) == len(df)
# 根据标题来判断是否有重复值  false

df.drop_duplicates("标题",inplace=True)
# 删除重复值

df.index = range(len(df))
# 删除之后,重排索引,为了之后拼接数据方便

print(len(df))
# 还有2244条数据



1.2 判断是否有缺失值

df.info()
'''

RangeIndex: 2244 entries, 0 to 2243
Data columns (total 10 columns):
 #   Column  Non-Null Count  Dtype  
---  ------  --------------  -----  
 0   标题      2244 non-null   object 
 1   价格      2244 non-null   float64
 2   小区名     2244 non-null   object 
 3   城市      2244 non-null   object 
 4   街道      2244 non-null   object 
 5   室厅数     2244 non-null   object 
 6   面积      2244 non-null   object 
 7   层数      2244 non-null   object 
 8   交接人     2244 non-null   object 
 9   详情链接    2244 non-null   object 
dtypes: float64(1), object(9)
memory usage: 175.4+ KB
'''

可以看到,全部数据没有缺失值,因此也不用处理缺失值。

若需要处理缺失值,可以选择:

  1. 直接删除存在缺失值的列,一般只有在缺失值占比太多的情况,才这样处理。
  2. 删除缺失值对应的数据,既删除对应的行,这种适用于当缺失值占比较小的情况。
  3. 填充缺失值。

下面给出处理确实值的具体方法:

# 查看所有缺失值数量,降序
total = df.isnull().sum().sort_values(ascending=False)

# 计算缺失值占比
percent = (df.isnull().sum()/df.isnull().count()).sort_values(ascending=False)

# 关联数量和占比
missing_data = pd.concat([total, percent], axis=1, keys=['Total', 'Percent'])

# 查看排名前20
missing_data.head(20)

# 根据之前计算的缺失值数据,删除对应的列
df = df.drop(missing_data[missing_data['Total'] > 1].index, 1)

# 删除某列数据缺失值对应的行
df = df.drop(df.loc[df['Electrical'].isnull()].index)

# 查看是否还有缺失值
df.isnull().sum().max()





二、简单分析数据

可以看到,数据中的城市、室厅数、层数、面积,都是文本形式,因此先将数据处理一下,转换成可计算的形式:


2.1 处理数据

# 将城市列分割,和数据拼接一起
df_city = pd.DataFrame(df["城市"].str.split("-").tolist(),columns=["区域","区域2"])
df = pd.concat([df,df_city],axis=1)

# 将室厅数拆解成室数和厅数,拼接在一起
df_st = pd.DataFrame(df["室厅数"].str.replace("厅","").str.split("室").tolist(),columns=["室","厅"])
df = pd.concat([df,df_st],axis=1)

# 层数数据不规范,将数据转换一下,转换为高/中/低层
df["层数2"] = df["层数"].replace(regex={"低层.*":"低层","中层.*":"中层","高层.*":"高层","共.*":"低层"})

# 面积中都带了“平方”,把它去掉
df["面积2"] = df["面积"].str[:-2].astype(float)

把我们需要的数据提取出来,由于是分析数据,多余的数据就不要了
col = ["区域","区域2","室","厅","层数2","面积2","小区名","价格","详情链接"]
df_r = df.loc[:,col]

col2 = ["区域","区域2","室","厅","层数","面积","小区名","价格","详情链接"]
df_r.columns = col2

df_r.head()



2.2 查看价格、面积的分布情况

df_r.describe()
'''
			面积			价格
count	2244.000000	2244.000000
mean	96.279813	12457.483957
std		123.089698	25630.815508
min		5.000000	700.000000
25%		20.000000	2300.000000
50%		59.800000	4600.000000
75%		110.000000	12000.000000
max		1260.000000	400000.000000
'''

好奇面积的最大值、价格的最大值的房子什么样子,筛选一下
df_r[df_r["价格"] == 400000]

df_r[df_r["面积"] == 1260]

相当的豪华,哈哈哈,有兴趣可以点进去看看详情。



价格的分布情况
con, rbin, ax = plt.hist(df_r["价格"],bins=8, color = 'steelblue', edgecolor = 'black')
s = (rbin[1]-rbin[0])/4
for x,y in zip(rbin,con):
    plt.text(x+s,y+20,'%.0f' % y,fontdict={'fontsize':11})

租房数据-数据分析_第1张图片


查看一下各个范围的准确值
hi_da = []
for i in range(len(con)):
    ran = f"{rbin[i]:.2f}-{rbin[i+1]:.2f}"
    cnt = con[i]
    hi_da.append([ran, cnt])
    
pd.DataFrame(hi_da, columns=["范围","计数"])
'''
			范围			计数
0	700.00-50612.50		2167.0
1	50612.50-100525.00	54.0
2	100525.00-150437.50	12.0
3	150437.50-200350.00	2.0
4	200350.00-250262.50	3.0
5	250262.50-300175.00	3.0
6	300175.00-350087.50	0.0
7	350087.50-400000.00	3.0
'''

可以看到大部分租房价格都在700至50612.5之间,接下来看看面积的分布情况



面积的分布情况
con, rbin, ax = plt.hist(df_r["面积"],bins=10, color = 'steelblue', edgecolor = 'black')
s = (rbin[1]-rbin[0])/4
for x,y in zip(rbin,con):
    plt.text(x+s,y+20,'%.0f' % y,fontdict={'fontsize':11})

租房数据-数据分析_第2张图片

查看一下各个范围的准确值

hi_da = []
for i in range(len(con)):
    ran = f"{rbin[i]:.2f}-{rbin[i+1]:.2f}"
    cnt = con[i]
    hi_da.append([ran, cnt])
pd.DataFrame(hi_da, columns=["范围","计数"])
'''
		范围			计数
0	5.00-130.50		1756.0
1	130.50-256.00	303.0
2	256.00-381.50	97.0
3	381.50-507.00	52.0
4	507.00-632.50	19.0
5	632.50-758.00	7.0
6	758.00-883.50	4.0
7	883.50-1009.00	3.0
8	1009.00-1134.50	1.0
9	1134.50-1260.00	2.0
'''

大部分面积都在5到130.5之间,从感觉上,面积和价格是成正比的,来看简单一下

plt.scatter(df_r['面积'], df_r['价格']);

租房数据-数据分析_第3张图片

跟我们猜测的差不多,就是有一些点,特别傲娇,没有符合我们的预期,哈哈哈。

我们猜测不至和面积有关,可能还和其他因素有关,接下来看看其他因素,对价格的影响吧。




2.3 区域、层数对价格的影响


各个区域的价格分布情况

先查看各个地区的租房个数
qu = df_r["区域"].value_counts()
'''
朝阳      632
海淀      475
丰台      258
通州      183
昌平      154
大兴      118
西城       94
石景山      83
东城       74
顺义       65
房山       46
门头沟      45
密云        9
怀柔        4
北京周边      3
延庆        1
Name: 区域, dtype: int64
'''

# 在每个地区名上加一个区字,用于下面的北京地图
n = [(x+"区",int(y)) for x,y in zip(qu.index,qu.values)]

为了更方便查看各个地区的租房个数,看一下它们的地理分布情况
from pyecharts import options as opts
from pyecharts.charts import Map

from pyecharts.globals import CurrentConfig, NotebookType
CurrentConfig.NOTEBOOK_TYPE = NotebookType.JUPYTER_LAB
map=Map(init_opts=opts.InitOpts(width='900px',height='800px'))
map.add(series_name='城市',data_pair=n,maptype='北京',is_roam=False)
map.set_global_opts(title_opts=opts.TitleOpts(title='北京租房数量'),visualmap_opts=opts.VisualMapOpts(max_=680))
map.load_javascript()
map.render_notebook()

注意load_javascriptrender_notebook不要一起执行,不然在jupyter-lab中输出不了地图。

(地图无法上传,大家自己运行代码吧)


可以看出来,朝阳区的租房数量最多,看看地区对价格的影响
var = "区域"
rank_r = df_r.groupby(by=var)["价格"].median().sort_values().index
data = pd.concat([df['价格'], df[var]], axis=1)
f, ax = plt.subplots(figsize=(8, 6))
fig = sns.boxplot(x=var, y='价格', data=data,order=rank_r)
fig.axis(ymin=0, ymax=100000);

租房数据-数据分析_第4张图片

可以看到,中位数高的前5个区域是顺义、东城、朝阳、西城和海淀,从地图上也大致看到这几个区域位于市中心。



各个层级的价格分布情况
df_r["层数"].value_counts()
'''
中层    835
低层    824
高层    585
Name: 层数, dtype: int64
'''
var = "层数"
rank_r = df_r.groupby(by=var)["价格"].median().sort_values().index
data = pd.concat([df['价格'], df[var]], axis=1)
f, ax = plt.subplots(figsize=(8, 6))
fig = sns.boxplot(x=var, y='价格', data=data,order=rank_r)
fig.axis(ymin=0, ymax=100000);

租房数据-数据分析_第5张图片

不出所料,由于低层更方便上下楼,低层的价格更高一点,而高层的中位数大于中层的是没有想到的,不过它们也非常接近。

以上分析都是分析单独变量,只做了区域和层级对价格的影响,接下来,看看它们之前都有什么关系。




三、分析数据间的相关性


由于层数这个数据是文本,不能进行计算,因此我们将它转换一下,转换成独热编码。
from sklearn.preprocessing import OneHotEncoder

# 初始化模型,并将数据转换
enc = OneHotEncoder()
enc.fit(df_r[["层数"]])
array_data = enc.transform(df_r[["层数"]]).toarray()

# 将数据拼接
df_ce = pd.DataFrame(array_data,columns=["中","低","高"])
df_r = pd.concat([df_r,df_ce],axis=1)

# 筛选数据,并将室厅数据转换为int类型
sn = ["区域","低","中","高","室","厅","面积","价格"]
df_rn = df_r.loc[:,sn]
df_rn.loc[:,["室","厅"]] = df_rn.loc[:,["室","厅"]].astype(int)

接下来看一下它们之间的相关性

corrmat = df_rn.corr()
f, ax = plt.subplots(figsize=(12, 9))
sns.heatmap(corrmat, vmax=.8, square=True);

租房数据-数据分析_第6张图片


可以看到右下角的数据相关性较高,其中和价格相关的有室、亭、面积,来看一下它们相关的具体数据:
corrmat["价格"]
'''
低     0.145677
中    -0.113269
高    -0.035243
室     0.508743
厅     0.572346
面积    0.740162
价格    1.000000
Name: 价格, dtype: float64
'''

可以看到面积和价格相关性达到了0.74,室、厅也和价格较相关,有时候可能直接的指标相关的较小,我们可以思考一下,怎么处理能让它们和价格更相关,最简单的,将它们最一些运算,来看看计算出来的指标,是否和价格更相关。

df_rn["室厅数"] = df_rn["室"]+df_rn["厅"]*2.5
df_rn.corr()["价格"]
'''
低      0.145677
中     -0.113269
高     -0.035243
室      0.508743
厅      0.572346
面积     0.740162
价格     1.000000
室厅数    0.608451
Name: 价格, dtype: float64
'''

我们可以看到,计算得出室厅数比它们单独的更相关。也就是说可以用室厅数更能解释价格。



四、数据标准化


实际的数据,总会有些不标准,不符合标准正态分布,之后进行预测数据时,会导致预测数据误差大,所以需要先将数据处理一下,叫做标准化。标准化的方法有很多,下面使用其中的一种,取对数。
from scipy.stats import norm
from scipy import stats

先看一下价格的偏度和峰度。

print("Skewness(偏度): %f" % df_rn["价格"].skew())
print("Kurtosis(峰度): %f" % df_rn["价格"].kurt())

'''
Skewness(偏度): 7.953787
Kurtosis(峰度): 91.264405
'''




偏度大于0,则分布偏右,即分布有一条长尾在右;峰度>0,分布陡峭;

Q-Q图也可以看数据的偏度和峰度。

sns.distplot(df_rn["价格"], fit=norm)
fig = plt.figure()
res = stats.probplot(df_rn["价格"], plot=plt)

租房数据-数据分析_第7张图片

租房数据-数据分析_第8张图片




可以看到数据的严重倾斜,下面使用对数来处理一下数据

df_rn["价格2"] = np.log(df_rn["价格"])
sns.distplot(df_rn["价格2"], fit=norm)
fig = plt.figure()
res = stats.probplot(df_rn["价格2"], plot=plt)

租房数据-数据分析_第9张图片

租房数据-数据分析_第10张图片

print("Skewness(偏度): %f" % df_rn["价格2"].skew())
print("Kurtosis(峰度): %f" % df_rn["价格2"].kurt())

'''
Skewness(偏度): 0.732321
Kurtosis(峰度): -0.092092
'''

可以看到数据偏度和峰度都得到了极大的修正。



最后再看一下修正后的价格和面积的分布情况吧

plt.scatter(df_rn['面积'], df_rn['价格2']);

租房数据-数据分析_第11张图片




五、总结


这次我们分析了,租房的信息,去重之后只有2244条数据,所以分析的结果难免会有误差,不过整体数据的相关性,分布情况,都进行了分析,接下来应该进行回归分析,来简单预测一下,在某个区域,某个面积,某个室厅数下,预测租到的房子价格。这个事情之后再做吧,哈哈哈。
以上就是所有的内容了。





你可能感兴趣的:(Python,pandas,数据分析,python)