【python】上海链家二手房交易数据分析

  • 目的:练习pandas数据处理以及数据可视化
  • 数据采集时间:2017/11/7
  • 数据获取:八爪鱼数据采集工具
  • 数据量:约3w条
  • 字段:行政区、小区名称、房型、楼层、朝向、单价、总价、建造年代等

1.数据预处理
——上海链家二手房交易数据分析-编程知识网

# 定义一个分列数据的函数工具用于将home_info和location_info的信息拆分出来
import pandas as pd 
def data_split(df_data):df_data = df_data.map(lambda x:x.replace('\n', ''))df_data = df_data.map(lambda x:x.replace(' ',''))df_data = df_data.map(lambda x:x+'|')df_data_0 = df_data.map(lambda x:x.split('|')[0])df_data_1 = df_data.map(lambda x:x.split('|')[1])df_data_2 = df_data.map(lambda x:x.split('|')[2])df_data_3 = df_data.map(lambda x:x.split('|')[3])df_data = pd.concat([df_data_0, df_data_1, df_data_2, df_data_3], axis=1)return df_data# 导入数据并预处理	
import pandas as pd 
import matplotlib.pylab as plt
from matplotlib.pylab import style
import datetime
starttime = datetime.datetime.now()
style.use('ggplot')     # 设置图片显示的主题样式
# 解决matplotlib显示中文问题
plt.rcParams['font.sans-serif'] = ['SimHei']  # 指定默认字体
plt.rcParams['axes.unicode_minus'] = False  # 解决保存图像是负号'-'显示为方块的问题
df_2 = pd.read_csv('.\lianjia_ershoufang_new.csv') 
print('数据集基本信息:')
print(df_2.info())
print('数据集共{}行,{}列'.format(df_2.shape[0],df_2.shape[1]))
print('原始数据预览:')
print(df_2.head())df_2 = pd.concat([df_2.iloc[:,:3],data_clean(df_2['home_info']),data_clean(df_2['location_info'])], axis=1)
df_2.columns =['travel', 'total_price', 'price','room_type', 'area', 'floor', 'orientation', 'area_name', 'district', 'location', 'built_year']# 为便于数据分析,去除数值中的汉字
df_2['built_year'] = df_2['built_year'].map(lambda x:x.replace('年建',''))
# 这一步是为了后面可以顺利将built_year转成int类型
for i in range(df_2.shape[0]):if df_2.loc[i,'built_year'] == '':df_2.loc[i,'built_year'] = 0else:pass
df_2['area'] = df_2['area'].map(lambda x:x.replace('平',''))
df_2.built_year = df_2.built_year.astype('int')
df_2['area'] = df_2['area'].astype('float64')
df_2.to_csv('.\lianjia_clean.csv', sep=',', index=False)   # 数据清洗完毕写入csv保存
endtime = datetime.datetime.now()
time_used = (endtime - starttime).seconds
print('数据预处理完成,共耗时%s秒' % time_used)
print('预处理后数据预览:')
df_2.head()

2.数据可视化

**2.1 总价、单价、面积和建造年代分布直方图**
fig = plt.figure(figsize=(15.0,10.0))
ax1 = fig.add_subplot(2,2,1)
ax2 = fig.add_subplot(2,2,2)
ax3 = fig.add_subplot(2,2,3)
ax4 = fig.add_subplot(2,2,4)fig.suptitle('链家二手房交易数据总览')df_totalprice = df_2[df_2['total_price'] < 4000]  # 略去总价4000w以上的数据
ax1.hist(df_totalprice['total_price'], bins=100, color='blue', alpha=0.7)
ax1.set_xlabel('总价')
ax1.set_ylabel('数量')ax2.hist(df_2['price'] , bins=100, color='blue', alpha=0.7)
ax2.set_xlabel('单价')
ax2.set_ylabel('房源数量')df_area = df_2[df_2['area'] < 400]  # 略去面积400平以上的数据
ax3.hist(df_area['area'], bins=100, color='blue', alpha=0.7)
ax3.set_xlabel('面积')
ax3.set_ylabel('房源数量')df_builtyear = df_2[df_2['built_year']>0] # 没有建造年代的标记为0,此处略去没有建造年代的数据
ax4.hist(df_builtyear['built_year'], bins=22, color='blue', alpha=0.7)
ax4.set_xlabel('建造年代')
ax4.set_ylabel('房源数量')plt.savefig('.\general_discription.png',dpi=200, bbox_inches='tight')
plt.show()

上海链家二手房交易数据分析-编程知识网

2.2 各区房价箱线图

import seaborn as sns
sns.set_style("whitegrid")from matplotlib.font_manager import FontProperties
myfont=FontProperties(fname=r'C:\Windows\Fonts\simhei.ttf',size=14)
sns.set(font=myfont.get_name()) # 解决seaborn中文显示为方框的问题plt.figure(figsize=(20.0,15.0))
ax = sns.boxplot(x="district", y="price",data=df_2[['district','price']])
ax.set_xlabel("上海各区",fontsize=20)
ax.set_ylabel("单价",fontsize=20)
plt.savefig('.\district_price.png',dpi=200, bbox_inches='tight') # 保存图片,设定图片分辨率,保证图片保存完整
plt.show()

上海链家二手房交易数据分析-编程知识网

2.3 获取各小区的经纬度,绘制房价地图

**2.3.1 获取各小区的经纬度**
import urllib
import jsonurl = 'http://api.map.baidu.com/geocoder/v2/'
ak = '&ak=C3KyxnzaNma4dXtTXZRSII10gu2Egq9W' # 调用百度地图API的密钥,个人可自由申请
city_name = '上海'
city_name = urllib.parse.quote(city_name) # 编码url链接中的中文部分
city = '&city=%s'%(city_name)
output = '&output=json&pois=0'lng = []
lat = []for i in range(0, df_2.shape[0]):area_name = df_2.loc[i,"area_name"]area_name = urllib.parse.quote(area_name)address = 'address=%s'%(area_name)url = 'http://api.map.baidu.com/geocoder/v2/'  # url初始化url = url + '?'+ address + city + output  + aktemp = urllib.request.urlopen(url)hjson = json.loads(temp.read())try:lng.append(hjson["result"]["location"]["lng"])lat.append(hjson["result"]["location"]["lat"])except:lng.append(None)lat.append(None)df_lng = pd.DataFrame(lng, columns=[['lng']])
df_lat = pd.DataFrame(lat, columns=[['lat']])df_2 = pd.concat([df_2, df_lng,df_lat], axis=1) # 将获得的经纬度信息更新到原始数据中df_loc = df_2[['area_name', 'price', 'lng', 'lat']].drop_duplicates() # 去重+去除空值
if df_loc.isnull().values.any():df_loc = df_loc.dropna()df_loc_group = df_loc.groupby(['area_name','lng', 'lat'], as_index=False)['price'].mean()
df_loc_group.to_csv('.\location.csv', index=False)**2.3.2 绘制房价地图**
from mpl_toolkits.basemap import Basemap
import matplotlib.pyplot as plt
import pandas as pd
import numpy as np
from matplotlib import cm
%matplotlib inlinemap = Basemap(projection='stere',lat_0=31,lon_0=121,\llcrnrlat=30,urcrnrlat=32,\llcrnrlon=120,urcrnrlon=122,\rsphere=6371200.,resolution='h',area_thresh=10)
map.drawmapboundary()   # 绘制边界
map.drawstates()        # 绘制州
map.drawcoastlines()    # 绘制海岸线
map.drawcountries()     # 绘制国家
map.drawcounties()      # 绘制县parallels = np.arange(30.,32.,.5) 
map.drawparallels(parallels,labels=[1,0,0,0],fontsize=10) # 绘制纬线meridians = np.arange(120.,122.,.5)
map.drawmeridians(meridians,labels=[0,0,0,1],fontsize=10) # 绘制经线lat = df_loc_group["lat"]                     # 获取纬度值
lon = df_loc_group["lng"]                   # 获取经度值
price = df_loc_group["price"]             # 获取平均房价cm = plt.cm.get_cmap('Reds') 
z = (price - price.min())/(price.max() - price.min())   # 绘制散点图时散点颜色深浅表示均价高低,颜色越深价格越高lon = np.array(lon)
lat = np.array(lat)
x,y = map(lon, lat)sc = map.scatter(x,y,marker=',',c=z,s=0.1,cmap=cm)    
plt.colorbar(sc)                         # 绘制颜色标尺
plt.title('上海房价分布图')
plt.savefig('.\homeprice_distibution_2.png', dpi=300, bbox_inches='tight')
plt.show()

上海链家二手房交易数据分析-编程知识网