二手市场比较分析 B和C部分的德国和法国汽车

哈Ha!

在这篇文章中,我想以德国和法国为例,分享使用几种python工具进行欧洲二手车市场比较分析的经验。

图片

从实现的角度来看,一切都会变得很香草。 所使用技术的动物园有点多余,因为它本身就是目的-我想对其进行测试。

背景 当我浏览法国广告网站时,进行这种分析的想法一次拜访了我。 我清楚地感觉到雪铁龙C3是一辆非常糟糕的汽车,每年会贬值20%,但是欧宝Corsa几乎是不朽的,因此它的价格不会随着年龄的增长而改变(否则价格会上升。劳力士)。 考虑到德国人认为成年人中的Corsa是专业实施方面惨败的标志,这是一个有趣的观察。 甚至有人开玩笑说,十年之内任何汽车都可以变成欧宝。 在没有西德Trabant的情况下,Zaporozhets在德国民间传说中的角色是由该特定品牌扮演的。 据我所知,C3在俄罗斯没有特别代表,但从标题图片上可以看出,它是经典2CV的精神继承者,这是一辆传奇性的汽车,错过了几年的互联网(1989年之前投入生产),并为驾驶员提供了惊人的9马力。

所以,开始做生意。 为了获得统计信息,您需要一个具有足够样本的来源。 在德国,这个法国的autoscout24.de是我所见过的最好的广播公司-www.lacentrale.fr (存在法语版的侦察兵,但不太受欢迎)。

我们将根据B类选择最受欢迎的一个,并在其中提出最初的问题(只需少量进入C类)。 为了收集数据,我们将选择过去10年中有数据且两个网站上至少有1000个广告的模型。 否则,样本将非常嘈杂。

如果您想要健康的人进行数据挖掘-如果您注册并获取了密钥,则autoscout会提供RESTful API

当然,我没有这样做,而是开始通过无头浏览器挖掘吸烟者。

Smoker挖掘看起来像这样-基于所需的过滤器(如下所述),我们形成一个查询字符串,并将其作为地址传递给PhantomJS无头浏览器(自从我安装它以来,由于某种原因它已被暂停)。

从这个阶段的非显而易见性开始,我增加了使用特征类加载元素的期望,该元素包含有关相应请求的选项数量的数据。

with io.open("dump.html", "w", encoding="utf-8") as f: f.write(html) try: element = WebDriverWait(browser, 20).until( EC.presence_of_element_located((By.CLASS_NAME, "cl-filters-summary-counter")) ) # wait until element with summry statistics is present or drop after 20 sec 

在浏览器中生成的html被馈送到BeautifulSoup解析器,我们在其中查找包含所找到结果的图形的元素。

 value = bsObj.findAll("span", {"class": "cl-filters-summary-counter"})[0].text value = value.replace(u'\xa0', u' ') # removes delimeter if results exceed 1000 

您可能会猜到,生成的请求包括模型,较小的价格和年龄范围,也就是说,存在大量请求,服务器断开连接的请求数超过500。 如果您想精美地解决问题,最好通过在过程中更改的代理来访问此类服务(并且如果您具有API密钥,则无需这样做)。 在Habré上,有一篇关于如何通过代理工作的精巧文章 。 我解决了技术含量低的问题-价格遵循年龄的线性规律,因此我确定了该范围的范围,并将请求限制为线性价格的+ .- 30-50%,并在请求之间引入了10秒的暂停时间。 这足以不被禁止。 收集一个模型的数据花了大约半个小时才在控制台中静默闪烁。

关于过滤器的几句话。 为了获得信息丰富的选择,我应用了以下过滤器:

  • 所有汽车均采用4-5门配置(Kors,Klio和其中一些提供的车型带有3门便宜的选装件)。
  • 所有汽车都带有4-5个座位-这是与前一个不同的功能,因为Clio,C3和308具有Société(企业)版本,并且市场上有很多这样的汽车-这些是所有电工和钳工的服务车,有一个盒子而不是后排座椅其他条件相同的情况下,它们的成本降低了几千欧。
  • 发动机功率限制为129 hp。 因为在此细分市场中进一步收费版本开始出现,那里的价格根本不符合其适度的状态。 如果重复Achtung-地址中的自动侦察兵使用的功率不是以马力为单位,而是以千瓦为单位。

发动机和变速箱不是专门的,但是在99%的发动机和变速箱中,它们是机械师,在法国,那里有很多柴油,仅仅是因为它是在柴油门出现前十年就被推广的。 现在,他们想把所有人都移植到他身边,从对政府道德如此善变的cha恼中解脱出来,法国人已经沉迷于他们第二受欢迎的民族消遣活动了两个星期,这是罢工和纵火。

数据被收集,并按模型在Excel文件中的表格中进行布局(没有Excel的数据,这是什么!谢谢openpyxl-为转移提供便利)。 为了可视化,所有模型上的所有数据都汇总在一个CSV文件中。

为了实现可视化,我想提交一个简单的Web界面。 原则上,当前版本不需要后端。 数据很少,处理是基本的,您可以将带有长JSON的所有内容与图形一起转储,然后在客户端进行处理。 但我想测试一下服务器,以便以后将其用于计算量不大的任务。 而且我不知道如何使用JS,因此我不得不用客户端来折磨自己,并且服务器也可以安装在python上,因为有工具。

为了实现服务器,我在以前修补过的bokeh和Plotly + Dash捆绑包之间感到痛苦。 在过去的许多任务中,我对bokeh感到非常满意,特别是因为它可以嵌入Jupyter笔记本电脑中(通过Jupyter Labs,并不是那么简单),而且无需启动bokeh服务器就可以很容易地在笔记本电脑中组织交互式组件()。 对于不知道如何使用JS的人,Bokeh是d3.js世界的门户。

对于此任务,我决定使用Plotly + Dash捆绑包(后者是不知道如何使用JS的人通往React世界的门户)。 该选择更有可能尝试。 从比较中可以看出-区别不是根本

我们继续执行接口。

我们正在拉起CSV,将其推到几个数据帧上。

为了正确设置页面样式并使用响应式设计,我们启用了本地CSS。

 app = dash.Dash(__name__, static_folder='assets') # resource folder app.scripts.config.serve_locally = True app.css.config.serve_locally = True 

接下来,我们使用一张两列表格创建最简单的布局,这是自适应布局的12种标准中的6种。

 app.layout = html.Div([ # include custom local css to allow two-column responsive html.Link(href='/assets/twocolumns_dash.css', rel='stylesheet'), html.Div([ # row div html.Div([ # column div html.H3('Average'), dcc.Graph(id='market-app', ), html.H4('Select model'), dcc.Dropdown(id='model_pick', options=model_options, value=None, multi=True) ], className="six columns"), html.Div([ # column div html.H3('Distribution'), dcc.Graph(id='market-app2', ), html.H4('Select year'), dcc.Slider( id='year-slider', min=years.min(), max=years.max(), value=years.min(), step=None, marks={str(year): str(year) for year in years} ) ], className="six columns"), ], className="row") ]) 

控件的功能实现非常简单-可以有很多输入,并且只有一种输出方式(例如,左图接受下拉菜单和Year滑块中的数据,但是只有一个元素可以更新,这是Dash功能,需要拐杖才能绕过)。

 @app.callback(Output('market-app2', 'figure'), [Input('model_pick', 'value'), Input('year-slider', 'value')]) def update_figure_dist(selected_models, year_picked): traces = [] for model in selected_models: traces.append(go.Bar( x=df_filtered.loc[model, year_picked, :].index.values.tolist(), y=df_filtered.loc[model, year_picked, :]['results'].values.tolist(), name=model )) return { 'data': traces, 'layout': go.Layout( xaxis={'title': 'price'}, yaxis={'title': 'offers'}, hovermode='closest', legend=dict(orientation="h", xanchor="center", y=1.2, x=0.5) ) } 

就绪界面-http://eu-carmarket.herokuapp.com/

对于德国数据,括号中是法国(FR)的(DE)。

在左侧,我们可以看到整个时期的平均价格。 此后,根据在网站上发布的规则,所有价格均为欧元-价格包括增值税。 右边是所选年份中按价格分配的报价。 该分布对于许多模型而言都是嘈杂的,因此在构建时,它以5个元素的核心在最近的邻居上进行了平滑处理(正是通过观察,我决定不采用广告数量少于1000个的模型)

那么我们在数据中看到了什么?

回答一个激励研究的问题-不,与永恒的Corsa相比,雪铁龙的贬值速度并不可怕。

图片

2017年的巨大价格差异并不是雪铁龙第一年的主要强劲贬值。 这实际上是他们向新一代过渡时价格的上涨。 现在,它们不再像旧的2CV雪铁龙,而是更像Mini车型,拥有时尚的十字准线用于分频器-时尚,时尚的青年。

如果您选择一种型号,那么德国和法国市场上的差异将是惊人的,因为它不存在,无论是价值还是折旧率都没有(尽管在法国,一辆失事的2年以上旧车只有在有锁车库的情况下才能找到)。

图片

图片

图片

如果您选择在俄罗斯IT人士中很受欢迎的市场来搬荷兰,那么您需要支付德国价格的20%,尽管事实上欧洲国家之间没有海关边界,但是如果不随身携带随身携带的随身物品而过境的话,仅运输已购买的汽车是行不通的。靠你 这要求您在前一个国家居住六个月以上。 否则,当您尝试对汽车进行注册时,所有预期的利益都会从您身上删除。

如果将一大堆模型进行比较,您会看到一些有趣的观察结果。 10年后,尽管标致,马自达或Seat的贬值比大众Polo,Opel Meriva或Skoda Fabia的贬值要大,但一切都收敛到大约一个点。 因此,是的,十年后,任何汽车都将成为欧宝,但不会成为Corsa,只有像C3这样的最爱才成为Corsa。

图片

折旧率与模型无关。 而来自全国。 与通用线性均匀性的偏差很小(例如Renault Megane
2016年的福特嘉年华(2017年的福特嘉年华)只是对模型一代的改变。

图片

图片

由于在这种情况下折旧不是一个物理概念,所以这并不意味着汽车将处于相同状态。 在法语中,会出现皱纹的侧面,擦伤,保险杠破裂,用透明胶带包裹的镜子以及数千公里外的跳棋游戏。 但是法国人深信折旧程度与德国人相同,并且按照他们的信念付款。 但是说服德国人购买二手车 法国司机和机械师的照顾下的汽车-他们会撒谎吗?

关于价格与俄罗斯相比。 有一个事实,就是所描述的许多模型都没有在俄罗斯出售。 在这两个市场的几个共同特征中,您可以在大众汽车网站上找到新的Polo(尽管在俄罗斯是轿车,在欧洲是掀背车)。 在俄罗斯,新价格为8300,​​在德国为13500,新价格为8300,​​将在2012年(在荷兰现有的价格中为16200,新价格)。 起亚里约各地都可以找到一个很好的比较:俄罗斯-9000,德国-11950(明显反对德国自卫主义的倾销),法国-13700,荷兰-19950(Ja-ja,一辆Kirusha的半喇嘛,价格是大众Tiguan / Hyundai Tussan / Nissan X -trail:拥抱,哭泣并记住如何踩踏自行车)。

Source: https://habr.com/ru/post/zh-CN433448/


All Articles