实战项目练习 ---- 链家二手房数据(清洗与合并篇)
2019-05-10 本文已影响0人
loannes
前言
现在已经学到了数据规整与合并这一章,为了加深对数据分析的理解接下来需要做个小项目练习一下。
目的
- 通过项目能够真实的了解到数据分析是做什么的
- 加深对pandas的熟悉程度
- 重新梳理一下目前学到的那些基础知识,查缺补漏
前期准备
此次项目准备对2018年北京链家网的二手房数据做一次分析
数据来源:Python数据科学的公众号
工具:暂时还是使用iTerm2,还未找到更合适的开发工具。Sublime Text2目前也在用,这次项目小不打算用这个。
导入数据文件并进行初步观察
这些观察包括了解数据特征的缺失值,异常值,以及大概的描述性统计。
In [10]: lianjia_df = pd.read_csv('lianjia/lianjia.csv')
# 先查看前5行数据
In [11]: lianjia_df.head(n=5)
In [12]: display(lianjia_df.head(5))
Direction District Elevator Floor Garden Id Layout Price Region Renovation Size Year
0 东西 灯市口 NaN 6 锡拉胡同21号院 101102647043 3室1厅 780.0 东城 精装 75.0 1988
1 南北 东单 无电梯 6 东华门大街 101102650978 2室1厅 705.0 东城 精装 60.0 1988
2 南西 崇文门 有电梯 16 新世界中心 101102672743 3室1厅 1400.0 东城 其他 210.0 1996
3 南 崇文门 NaN 7 兴隆都市馨园 101102577410 1室1厅 420.0 东城 精装 39.0 2004
4 南 陶然亭 有电梯 19 中海紫御公馆 101102574696 2室2厅 998.0 东城 精装 90.0 2010
In [14]: lianjia_df.info()
<class 'pandas.core.frame.DataFrame'>
RangeIndex: 23677 entries, 0 to 23676
Data columns (total 12 columns):
Direction 23677 non-null object
District 23677 non-null object
Elevator 15440 non-null object
Floor 23677 non-null int64
Garden 23677 non-null object
Id 23677 non-null int64
Layout 23677 non-null object
Price 23677 non-null float64
Region 23677 non-null object
Renovation 23677 non-null object
Size 23677 non-null float64
Year 23677 non-null int64
dtypes: float64(2), int64(3), object(7)
memory usage: 2.2+ MB
可以很直接的看到Elevator
的值存在着大量的缺失,那先对缺失数据做处理。这里其实可以做填充,因为正常情况下楼层高于6层的都会有电梯,相反则没有。
In [71]: lianjia_df['Elevator'].value_counts()
Out[71]:
有电梯 9342
无电梯 6078
精装 11
毛坯 7
简装 2
看到在Elevator
中存在精装、毛培等异常值,先删除
In [75]: lianjia_df['Elevator'] = lianjia_df.loc[(lianjia_df['Elevator'] == '有电梯') | (lianjia_df['Elevator']=='无电梯'), 'Elevator']
In [76]: lianjia_df['Elevator'].value_counts()
Out[76]:
有电梯 9342
无电梯 6078 # 总共23000多条数据,这里明显不够,说明有大量空缺值
Name: Elevator, dtype: int64
再填充电梯情况:
# 这里要直接修改数据了,所以先copy一下
In [90]: df = lianjia_df.copy()
In [91]: df.loc[(df['Floor'] > 6) & (df['Elevator'].isnull()), 'Elevator'] = '有电梯'
In [92]: df.loc[(df['Floor'] <=6) & (df['Elevator'].isnull()), 'Elevator'] = '无电梯'
In [96]: df['Elevator'].value_counts()
Out[96]:
有电梯 14025
无电梯 9652
# 现在
现在空缺值处理完成了,接下来检查下有没有异常值情况:
In [14]: lianjia_df_dorped.describe()
Out[14]:
Floor Id Price Size Year
count 15440.000000 1.544000e+04 15440.000000 15440.000000 15440.000000
mean 13.037435 1.011023e+11 622.969326 99.059909 2001.132124
std 7.651691 5.934382e+05 411.791294 47.552860 8.804468
min 1.000000 1.010886e+11 68.500000 2.000000 1950.000000
25% 6.000000 1.011022e+11 378.000000 66.000000 1997.000000
50% 11.000000 1.011024e+11 510.000000 89.000000 2003.000000
75% 18.000000 1.011026e+11 730.000000 119.250000 2007.000000
max 57.000000 1.011028e+11 6000.000000 1019.000000 2016.000000
虽然不大清楚北京有没有价值6000万的房子,但是2平方以及1019平方的房子这个肯定是不现实的。看一下数据情况:
In [17]: df.loc[df['Size'] < 20]
Out[17]:
Direction District Elevator Floor Garden Id Layout Price Region Renovation Size Year
134 西 沙河 有电梯 17 北街家园七区 101102651491 1室1厅 180.0 昌平 简装 19.0 2010
1168 240.97平米 长阳 毛坯 5 世茂维拉 101102253577 叠拼别墅 1080.0 房山 南北 5.0 2015
1458 242.78平米 长阳 毛坯 5 世茂维拉 101102217569 叠拼别墅 1100.0 房山 南北 5.0 2015
1797 242.96平米 长阳 精装 5 世茂维拉 101101911559 叠拼别墅 980.0 房山 南北 5.0 2015
2268 295.88平米 顺义其它 精装 4 龙湖好望山 101102431983 叠拼别墅 1000.0 顺义 南北 4.0 2014
2274 295.01平米 顺义其它 精装 4 鹭峯国际 101102300614 叠拼别墅 1450.0 顺义 南北 5.0 2014
2276 292.31平米 顺义其它 毛坯 3 龙湖好望山 101102013095 叠拼别墅 860.0 顺义 南北 4.0 2014
2432 294.42平米 顺义其它 精装 5 龙湖好望山 101101141445 叠拼别墅 980.0 顺义 南北 6.0 2013
4078 427.5平米 西红门 精装 3 鸿坤林语墅 101102023530 叠拼别墅 3150.0 大兴 南北 4.0 2015
4079 361.8平米 西红门 精装 4 鸿坤林语墅 101102460862 叠拼别墅 2380.0 大兴 南北 4.0 2015
4761 386.83平米 西红门 精装 3 鸿坤林语墅 101102411099 叠拼别墅 2700.0 大兴 南北 5.0 2015
7533 107.93平米 回龙观 简装 4 龙城花园N区 101101993058 叠拼别墅 620.0 昌平 南北 2.0 1997
8765 195.32平米 通州其它 毛坯 6 旭辉御锦 101102638903 叠拼别墅 780.0 通州 南北 5.0 2014
9020 259.87平米 通州其它 精装 6 旭辉御锦 101101801342 叠拼别墅 1120.0 通州 南北 4.0 2014
9080 259.76平米 通州其它 毛坯 6 旭辉御锦 101102046256 叠拼别墅 1050.0 通州 南北 4.0 2014
9203 260.07平米 通州其它 精装 6 旭辉御锦 101102490792 叠拼别墅 1050.0 通州 南北 4.0 2014
9254 264.6平米 通州其它 毛坯 6 旭辉御锦 101102440907 叠拼别墅 1100.0 通州 南北 4.0 2014
11531 335.51平米 丽泽 毛坯 6 西宸原著 101102306757 叠拼别墅 4000.0 丰台 南北 4.0 2016
14298 266.61平米 西山 精装 3 中间建筑一区 101101869900 叠拼别墅 1350.0 海淀 南北 8.0 2007
15334 203.73平米 西山 简装 4 西山美墅馆F区 101102520575 叠拼别墅 2200.0 海淀 南北 4.0 2004
17311 523.4平米 大望路 精装 5 首府官邸 101102432328 叠拼别墅 4500.0 朝阳 南北 5.0 2007
22350 南 东四 有电梯 3 华人一品阁 101101915230 1房间1卫 90.0 东城 简装 16.0 2006
22393 南 东四 有电梯 3 华人一品阁 101101915213 1房间1卫 90.0 东城 简装 16.0 2006
我觉得16平的房子应该会有,但是小于10平方的房子肯定是异常数据,删掉!
In [30]: df = df[df['Size'] > 10]
In [32]: df.describe()
Out[32]:
Floor Id Price Size Year
count 15420.000000 1.542000e+04 15420.000000 15420.000000 15420.000000
mean 13.048314 1.011023e+11 621.608067 99.182490 2001.117639
std 7.650579 5.936816e+05 408.445645 47.461617 8.799356
min 1.000000 1.010886e+11 68.500000 16.000000 1950.000000
25% 6.000000 1.011022e+11 377.750000 66.000000 1997.000000
50% 11.000000 1.011024e+11 510.000000 89.000000 2003.000000
75% 18.000000 1.011026e+11 730.000000 120.000000 2007.000000
max 57.000000 1.011028e+11 6000.000000 1019.000000 2016.000000
同样平方大的离谱的异常值也要删除
In [34]: df.loc[df['Size'] > 1000]
Out[34]:
Direction District Elevator Floor Garden Id Layout Price Region Renovation Size Year
8754 南 通州其它 有电梯 8 新华联科技大厦 101102019411 1房间0卫 1700.0 通州 简装 1019.0 2009
发现这个大于1000平的是个办公楼,属于异常删掉
In [35]: df = df.loc[df['Size'] < 1000]
Size
数据异常的也清理掉了
In [36]: df.describe()
Out[36]:
Floor Id Price Size Year
count 15420.000000 1.542000e+04 15420.000000 15420.000000 15420.000000
mean 13.048314 1.011023e+11 621.608067 99.182490 2001.117639
std 7.650579 5.936816e+05 408.445645 47.461617 8.799356
min 1.000000 1.010886e+11 68.500000 16.000000 1950.000000
25% 6.000000 1.011022e+11 377.750000 66.000000 1997.000000
50% 11.000000 1.011024e+11 510.000000 89.000000 2003.000000
75% 18.000000 1.011026e+11 730.000000 120.000000 2007.000000
max 57.000000 1.011028e+11 6000.000000 1019.000000 2016.000000
再看看其他数据有异常或者空缺情况
In [101]: df['Renovation'].value_counts()
Out[101]:
精装 11345
简装 8497
其他 3239
毛坯 576
南北 20
Name: Renovation, dtype: int64
发现在Renovation
变量上多了“南北”这种异常数据,删除掉
In [105]: df= df.loc[(df['Renovation'] != '南北')]
In [106]: df['Renovation'].value_counts()
Out[106]:
精装 11345
简装 8497
其他 3239
毛坯 576
Name: Renovation, dtype: int64
检查过后已经没有任何异常数据和空缺值了。
总结
- 最大的感触是还是得使用个编辑器,否则一不小心改错数据后又得重头再来
- 检查数据的过程中有很多异常数据会隐藏的很深,光查看概览是不够的还需要去查看变量的统计
- 有些数据是可以通过其他数据来做填充,如果出现大量数据空缺的情况尽量优先考虑填充而不是清除