Bootstrap

用python描述车_使用Python探索二手车市场(含代码)

原标题:使用Python探索二手车市场(含代码)

感谢关注天善智能,走好数据之路↑↑↑

欢迎关注天善智能,我们是专注于商业智能BI,人工智能AI,大数据分析与挖掘领域的垂直社区,学习,问答、求职一站式搞定!

对商业智能BI、大数据分析挖掘、机器学习,python,R等数据领域感兴趣的同学加微信:tstoutiao,邀请你进入数据爱好者交流群,数据爱好者们都在这儿。

前言

上一期中,我们已经手把手的分享了如何使用Python实现某二手车平台数据的抓取,并成功的完成11,281条二手车数据的搜集。基于此,我们需要对获取的数据进行探索性分析,这里就采用我们之前学习的pandas模块和matplotlib模块的知识点做一个小小的数据分析项目。

数据清洗

我们再来看一下爬虫后获取数据的前几行,便于读者清楚的了解数据结构,各变量分别代表汽车品牌、汽车款式、上牌时间、行驶里程数、排放标准、二手价格和同款新车的参考价格:

从数据的前6行我们可以发现数据的一些问题,包括二手车的上牌时间,有的样本记录为“未上牌”,需要特殊处理、行驶里程数为字符串,需要类型的转化、新车原价也是字符串,也需要处理、上牌时间为字符串,如何计算上牌时间与当前10月份的时间差(月数)。而这些问题的解决,就需要我们进行数据清洗工作。

上牌时间字段的处理

由于上牌时间字段存在“未上牌”的值,我们需要看看这样的值占多大比例,如果比例不大,可以考虑将其删除。

# 导入第三方模块

import pandas as pd

import numpy as np

import matplotlib.pyplot as plt

from sklearn.linear_model import LinearRegression

# 可视化的中文处理

plt.rcParams['font.sans-serif'] = 'Microsoft YaHei'

plt.rcParams['axes.unicode_minus'] = False

# 设置类似R语言中的ggplot2风格

plt.style.use('ggplot')

# 读取数据(记得需要将csv文件先另存为UTF-8的编码,否则会报编码错误)

cars = pd.read_csv('second_cars_info.csv')

# “未上牌”的二手车占比

N = np.sum(cars.Boarding_time == '未上牌')Ratio = N/cars.shape[0]Ratio

# 由于未上牌的汽车数量占比极少,仅千分之八,这里不妨考虑将其删除

cars = cars.loc[cars.Boarding_time != '未上牌',:]

由于上面的清洗步骤,导致一些观测被删除,此时的行索引就不再是一个连续的自然数了,故需要重新设置索引,以免产生不必要的错误(因为pandas模块中数据结构的行索引会自动对齐)。

# 重新设置行索引

cars.index = range(0,cars.shape[0])

# 取出上牌时间变量中的年和月

cars['year'] = cars.Boarding_time.str[:4].astype('int')month = cars.Boarding_time.str.findall('年(.*?)月')

print(month.head(10))

# 由于month是列表构成的序列,所以需要非列表化,再序列化

month = pd.Series([i[0] for i in month]).astype('int')cars['month'] = month

# print(month.head(10))

# 计算上牌日期距离2017年10月份的月数

cars['diff_months'] = (2017-cars.year)*12 + (10-cars.month) + 1

# 显示数据的前5行

cars.head()

行驶里程数字段的处理

行驶里程数为字符串,要实现字符串转数值,需要先将字段中的“万公里”字样去除,然后再进行数据类型的转换。

# 剔除“万公里”三个字

cars['Km_new'] = cars.Km.str[:-3]

# 数值类型转换

cars.Km_new = cars.Km_new.astype('float')

哎?这里报错了,原因是行驶公里数字段中含“百公里内”这样的值,所以剔除该字段末尾3个字符之后,还剩余“百”字,导致了无法将“百”实现数值的转化。

# “百公里内”的样本量

N = np.sum(cars.Km == '百公里内')Ratio = N/cars.shape[0]Ratio

行驶里程数为“百公里内”的样本量仅仅只有63条,占比为千分之六,我们不妨将“百公里内”的样本替换成50公里,即0.005万公里。

# 将“百”字替换为0.005

cars.Km_new.replace('百','0.005', inplace=True)

# 数据类型转换

cars.Km_new = cars.Km_new.astype('float')cars.head()

同款新车价格字段的处理

从上面的数据结构可知,同款新车的参考价格都存在“万”字,要想实现数据类型的转换,同样先是将“万”字去掉,然后进行数值转换。

# 删除字段中的“万”字

cars['New_price_new'] = cars.New_price.str[:-1]

#cars.New_price_new.astype('float')

# 这里无法实现数据类型的转换,因为该字段中含有“暂无”这样的值。

# “暂无”的样本量

N = np.sum(cars.New_price == '暂无')Ratio = N/cars.shape[0]Ratio

由于本人对车子的了解情况甚少,无法对“暂无”的价格进行评估,不妨就将这1.3%的样本作剔除处理。

cars = cars.loc[cars.New_price != '暂无',:]

# 数据类型的转换

cars.New_price_new = cars.New_price_new.astype('float')cars.head()

经过上面的数据清洗工作,数据中有一部分被删除,也有一部分值被替换。通过数据框结构的shape方法,可知目前数据集还剩下11,047个样本,一共减少了234条二手车样本。最后,我们再来看看数据集的概览情况:

# 数据集的概览信息cars.describe()

采用可视化方法进行数据探索

直方图的绘制

我想大家一定也和我一样,最关心的是二手车的价格分布吧,看看二手车的价格都落在什么范围内?首先,我们对二手车的价格绘制一张直方图,看看其分布形状。

# 二手车价格分布情况

min_price = cars.Sec_price.min()max_price = cars.Sec_price.max()

# 直方图

plt.hist(cars.Sec_price, # 二手车价格数据 bins = np.arange(min_price,max_price+10,10), # 以10万元为组距 color = 'steelblue', # 指定填充色 )

# 设置坐标轴标签和标题

plt.title('二手车价格分布直方图')plt.xlabel('价格')plt.ylabel('频数')

# 去除图形顶部边界和右边界的刻度

plt.tick_params(top='off', right='off')

# 图形显示

plt.show()

图形明显呈现偏态分布,并且是右偏长尾,即随着二手车价格越高,车子的数量就下降的越多。那请问,多少比例的二手车会落在某个价格范围内呢?这个问题的回答,可以借助于累计频率直方图来展示。

# 累积频率直方图

plt.hist(cars.Sec_price, # 二手车价格数据

bins = np.arange(min_price,max_price+10,10), # 以10万元为组距

normed = True, # 设置为频率直方图

cumulative = True, # 积累直方图

color = 'steelblue', # 指定填充色 )

# 添加水平参考线

plt.axhline(y = 0.5, color = 'blue', linestyle = '--', linewidth = 2)plt.axhline(y = 0.8, color = 'red', linestyle = '--', linewidth = 2)

# 设置坐标轴标签和标题

plt.title('二手车价格累积分布直方图')plt.xlabel('价格')plt.ylabel('累积频率')

# 去除图形顶部边界和右边界的刻度

plt.tick_params(top='off', right='off')

# 图形显示

plt.show()

从这个累积直方图可知,一半的二手车价格在10万以内,就整体而言,80%的二手车均在30万以内。哈哈,如果你有想法,可以去二手车市场观望观望哦。

条形图的绘制

上面的直方图,其实质反映的就是等间距的条形图。如果需要自定义价格范围,然后基于这个范围再作条形图的绘制,该如何操作呢?这里需要借助于pandas模块中的cut函数,将连续的数值切割成不同的数据段:

很显然,从这个自定义的分段数据中,5~8万的二手车最多,占了17.72%,其次是3~5万,也占了16.21%。从总体的排序来看,10万以内的二手车数量,排在了前3。

饼图的绘制

关心完了二手车的价格,是不是该关心一下这辆车跑了多少路了?毕竟二手车的价格跟行驶里程数也是有关系的嘛。我们按照二手车网站的筛选条件,将行驶里程数分割为5段,即1万公里以内、1~3万公里、3~5万公里、5~10万公里及10万公里以上。

从饼图返回的信息可知,超过一半的车,其行驶里程数在5~10万公里,而占比最少的是1万公里以内的二手车,6%不到。

散点图的绘制

影响二手车价格的因素可能二手车的行驶时长、行驶公里数和汽车品牌,直观感觉,二手车的价格应该与行驶时长、行驶公里数成反向关系,即行驶时长或行驶公里数越大,则二手车的价格应该越便宜。接下来我们来探索一下,是不是这么个道理,由于二手车的品牌也严重影响价格,故这里以奥迪和大众为例,绘制散点图。

很显然,从图中可知,二手车的行驶里程数与价格成反向关系,似乎奥迪车显示的更为明显。接下来我们再来看看二手车的行驶时长与价格之间是否也是反向关系,这里就以奥迪车为例了,同时,我们也在散点图的基础上再添加一条回归线。

# 取出奥迪车的数据子集

aodi_car = cars.loc[cars['Brand'] == '奥迪',:]

plt.scatter(aodi_car.diff_months,

aodi_car.Sec_price,

s = 30, # 设置点的大小

c = 'steelblue', # 设置点的颜色

marker = 'o', # 设置点的形状

alpha = 0.9, # 设置点的透明度

linewidths = 0.3, # 设置散点边界的粗细

label = '观测点')

# 建模

reg = LinearRegression().fit(aodi_car.diff_months.reshape(-1,1), aodi_car.Sec_price)

# 回归预测值

pred = reg.predict(aodi_car.diff_months.reshape(-1,1))

# 绘制回归线

plt.plot(aodi_car.diff_months, pred, linewidth = 2, label = '回归线')

# 添加轴标签和标题

plt.title('二手车的行驶时长与价格的关系')plt.xlabel('行驶时长(月)')plt.ylabel('价格(万元)')

# 去除图边框的顶部刻度和右边刻度

plt.tick_params(top = 'off', right = 'off')

# 显示图例

plt.legend(loc = 'best')# 显示图形

plt.show()

OK,感觉上还是蛮准确的,即二手车的行驶时长与价格之间确实存在反向关系。从图中我们也发现一些远离总体的异常点,即价格在100万以上的,我想这些都是顶级高档的奥迪汽车了吧。但不管怎样,这些“异常点”也符合行驶时长与价格之间反向关系。

结语

OK,关于二手车的探索性分析案例,我们就分享到这里,但感兴趣的你,一定要动手操作一遍,否则还是走马观花的效果哦。如果你有问题,欢迎在公众号的留言区域表达你的疑问。同时,也欢迎各位朋友继续转发与分享文中的内容,让跟多的人学习和操作。

本文相关的Python脚本和PDF版本已存放到百度云盘,可以加 tstoutiao 获取。

本文作者:天善智能社区专家刘顺祥,每天进步一点点2015

天善智能社区爬虫课程推荐:https://edu.hellobi.com/course/156

Python网络爬虫实战 https://edu.hellobi.com/course/81

天善学院svip正限时特惠火爆报名中!包含业务知识一站通、Excel BI商业智能、七周成为数据分析师、对话大数据系列技术、R语言15案例、Python3网络爬虫实战案例、Python机器学习、Python数据科学家精华实战课程、深度学习模型和实战课程、数据分析报告共10套课程,其他课程只需五折即可,欢迎大家关注报名。https://www.hellobi.com/svip返回搜狐,查看更多

责任编辑:

;