在线房源数据分析

通过Python爬虫抓取链家网二手房源数据,分析了房源数量、均价、位置等信息,进行了数据清洗,去除异常值,对房源进行了聚类分析,探讨了不同区域的房源数量、均价及小区数量。
  • 针对链家二手房源的数据,利用python分析房源数量,均价,位置等信息
  • 数据来源:https://github.com/XuefengHuang/lianjia-scrawler
    该repo提供了python程序进行链家网爬虫,并从中提取二手房价格、面积、户型和二手房关注度等数据。

1. 导入链家网二手房在售房源的文件

import pandas as pd 
import numpy as np
import matplotlib.pyplot as plt 
import seaborn as sns
from matplotlib import font_manager
import warnings

warnings.filterwarnings("ignore")
my_font = font_manager.FontProperties(fname="/System/Library/Fonts/PingFang.ttc")
house = pd.read_csv("./houseinfo.csv", index_col="houseID", usecols=(0, 1, 3, 4, 5, 6, 9, 10, 11, 12, 13))
print(house.shape)
house.head()

2.数据清洗

# 2.1 查看缺失值
house.isnull().sum()
# years和taxtype不是重点研究,先不处理缺失值
# 2.2 将字符串转换成数字
# 处理square
house["square"] = house["square"].str.replace("平米", "")
house["square"].sample(10)

# 查看是否可以转换成字符型
# 发现有些数据无法转换, 可以用以下函数先进行判定,找出无法转换成数值类型的行
# house["square"] = house["square"].astype("f8")
def is_transform(x):
    try:
        float(x)
        return True
    except ValueError:
        return False
house["square"].apply(is_transform).value_counts()

# 查看问题行
house[~house["square"].apply(is_transform)].head()
# 发现有问题的行是因为户型是别墅,先不删除

3. 房源信息数据分析

# 3.1 删除车位
chewei = house[house["housetype"] == "车位"]
print(f"一共有{chewei.shape[0]}个车位")
# 删除车位信息
index = chewei.index
house.drop(index=index, inplace=True)
print(f"一共还有{house.shape[0]}个记录")

一共有32个车位
一共还有16076个记录

# 3.2 删除别墅信息
bieshu = house[house["housetype"].str.contains("别墅")]
# 查看价格前五的别墅
bieshu.sort_values(by="totalPrice", ascending=False)[["title", "community", "housetype", "square", "totalPrice", "unitPrice"]].head()

# 删除这50个别墅信息
house.drop(index=bieshu.index, inplace=True)
print(f"一共还有{house.shape[0]}个记录")

一共还有16026个记录

# 3.3 将square列的字符串转换成数字
house["square"] = house["square"].str.replace("平米", "")
house["square"] = house["square"].astype("f8")
house.describe()

# 3.4 获取总价前五的房源信息
house.sort_values(by = "totalPrice", ascending=False).head()

# 3.5 获取户型数量分布信息
house_type = house["housetype"].value_counts().head(10)
house_type.plot(kind="bar", figsize=(10, 6), rot=0)
plt.xticks(fontproperties=my_font)
plt.show()

# 3.6 关注人数最多5套房子
def str_to_int(data, str_):
    if str_ in data:
        return int(data[0: data.find(str_)])
    else:
        return None

house["followInfo"] = house["followInfo"].apply(str_to_int, str_ = "人关注")
house.describe()

# 获取关注人数最多的5套房子
house.sort_values(by = "followInfo", ascending=False).head()

# 3.7 户型和关注人数分布
fig = plt.figure(figsize=(16, 6), dpi=80)

type_intere_house = house["followInfo"].groupby(house["housetype"]).agg([("户型", "count"), ("关注人数", "sum")])
ti_sort = type_intere_house[type_intere_house["户型"] > 50].sort_values(by="户型", ascending=False)

ax1 = fig.add_subplot(1, 2, 1)
ax1.bar(x= ti_sort["户型"].index, height=ti_sort["户型"].values, color="g", label="户型")
plt.xticks(fontproperties=my_font, rotation=45)
plt.legend(prop=my_font)

ax2 = fig.add_subplot(1, 2, 2)
ax2.bar(x= ti_sort["关注人数"].index, height=ti_sort["关注人数"].values, label="关注人数")
plt.xticks(fontproperties=my_font, rotation=45)
plt.legend(prop=my_font)

# 3.8 面积分布
bins = [0, 50, 100, 150, 200, 250, 300, 1000, 3000]
count_bins = pd.cut(house["square"], bins=bins)
# 从小到大排列
# count_bins.value_counts()
square_house = house["square"].groupby(count_bins).count()
square_house.index = [str(x.left) + "~" + str(x.right) for x in square_house.index ]
square_house.plot(kind="bar", rot=0, figsize=(10, 6), grid=True)

plt.title('二手房面积分布', fontproperties=my_font)    
plt.xlabel('面积', fontproperties=my_font)    
plt.legend(['数量'], prop=my_font)    
plt.show()

# 在售的最小和最大面积的房
square_house = house["square"].sort_values(ascending=False)
print(f"北京在售面积最小的房: {square_house.iloc[0]}")
print(f"北京在售面积最大的房: {square_house.iloc[-1]}")

北京在售面积最小的房: 2623.28
北京在售面积最大的房: 15.29

# 3.9 聚类分析
# 缺失值处理:直接将缺失值去掉
cluster_data = house[["square", "followInfo", "totalPrice"]]
# 查看缺失值, 发现没有缺失值
cluster_data.isnull().sum()

# 导入KMeans库
from sklearn.cluster import KMeans
kmeans = KMeans(n_clusters=3)
kmeans.fit(cluster_data)
center = pd.DataFrame(kmeans.cluster_centers_, columns=["square", "followInfo", "totalPrice"])
print("聚类中心是:")
display(center)

4. 小区信息数据分析

# 读取community数据集
community = pd.read_csv("./community.csv", usecols=(0, 1, 3, 4, 5, 6))
display(community.head())

# 将两张表关联起来
community.rename(columns={"title": "community"}, inplace=True)
house_detail = pd.merge(house, community, on="community")
house_detail.head()

# 4.1 各个行政区房源均价
house_unitprice_perdistrict = house_detail["unitPrice"].groupby(house_detail["district"]).mean()
display(house_unitprice_perdistrict)

house_unitprice_perdistrict.plot(kind="bar", x='district',y='unitPrice', figsize=(10, 6), rot=0)
plt.title(fontproperties=my_font, label='各个行政区房源均价')
plt.xticks(fontproperties=my_font)
plt.legend(["均价"], prop=my_font)
plt.show()

district
东城 99213.937557
朝阳 70409.512836
海淀 86156.285400
西城 106122.371675
Name: unitPrice, dtype: float64

# 4.2 各个区域房源数量排序
bizcircle_count = house_detail.groupby("bizcircle").size().sort_values(ascending=False)
bizcircle_count.head(20).plot(kind='bar',x='bizcircle',y='size', title='各个区域房源数量分布', figsize=(10, 6))
plt.legend(['数量'], prop=my_font) 
plt.xticks(fontproperties=my_font)
plt.title('各个区域房源数量分布', fontproperties=my_font)
plt.show()

# 4.3 各个区域均价排序
bizcircle_price = house_detail.groupby("bizcircle").mean()["unitPrice"].sort_values(ascending=False)
bizcircle_price.head(20).plot(kind='bar', figsize=(10, 6))
plt.legend(['均价'], prop=my_font) 
plt.xticks(fontproperties=my_font)
plt.title('各个区域房源价格均值', fontproperties=my_font)
plt.show()

# 4.4 各个区域小区数量
bizcircle_num = community.groupby("bizcircle").count()["community"].sort_values(ascending=False)
bizcircle_num.head(20).plot(kind='bar', figsize=(10, 6))
plt.legend(['数量'], prop=my_font) 
plt.xticks(fontproperties=my_font)
plt.title('各个区域小区数量', fontproperties=my_font)
plt.show()

# 4.5 按小区均价排序
community_price = house_detail.groupby("community").mean()["unitPrice"].sort_values(ascending=False)
community_price.head(20).plot(kind='bar', figsize=(10, 6))
plt.legend(['均价'], prop=my_font) 
plt.xticks(fontproperties=my_font)
plt.title('各个小区均价', fontproperties=my_font)
plt.show()
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值