表弟准备买房,让我帮他分析分析哪个小区最合适,我直接用python下载了本地所有房源信息做成了可视化图

人工智能36

文章目录

表弟刚毕业工资2500,节衣缩食一年准备买200W左右的房,让我帮他参谋一下房子买哪里好,买房过程简直太励志了!

通过他辛苦工作一年终于攒下五千块,最后在家里支援了199.5W后,成功全款拿下房子...

表弟准备买房,让我帮他分析分析哪个小区最合适,我直接用python下载了本地所有房源信息做成了可视化图
这谁顶得住啊😳

算了我们还是回到文章吧 ~

; 📢准备工作

软件

python 3.8 解释器
pycharm 专业版2021.2

不会安装的可以看我零基础系列都有讲

使用的模块及安装

requests >>> pip install requests 数据请求 (用python代码 模拟浏览器对于服务器发送请求)
parsel >>> pip install parsel 数据解析 (提取我们想要数据内容)  parsel 对于你们以后学习scrapy(核心组件之一)有帮助
csv 内置模块 不需要安装 获取到的数据内容保存到csv表格数据

win+r 输入cmd,输入安装命令 pip install 加上模块名

爬虫通用流程思路

1.明确需求(抓取内容: 视频数据/音频数据/图片)
2.发送请求: 对应分析得到url
3.获取数据: response.text[文本数据 网页源代码] response.json()[json字典数据] response.content(二进制数据)
4.解析数据(提取我们想要数据内容) 解析方式: css xpath re
5.保存数据(保存csv表格) 视频/图片/音频/文字...文件 本地 数据库

数据来源分析

爬虫: 对于网页上面的数据内容进行采集程序

1. 确定爬取的内容是什么东西?

    二手房源的基本数据
2. 通过开发者工具进行抓包分析, 分析这些数据内容是可以哪里获取
    通过开发者工具, 分析可得 >>> 我们想要的房源数据内容(房源详情页url) 就是来自于 网页源代码
    如果你要爬取多个房源数据, 只需要在列表页面 获取所有的房源详情页url

代码实现步骤:

发送请求 >>> 获取数据 >>> 解析数据 >>> 保存数据

1. 发送请求, 是对于房源列表页发送请求 https://cs.***.com/ershoufang/
2. 获取数据, 获取网页源代码 response.text
3. 解析数据, 提取我们想要的内容, 房源详情页url
4. 发送请求, 对于房源详情页url地址发送请求
5. 获取数据, 获取网页源代码 response.text
6. 解析数据, 提取房源基本信息 售价 标题 单价 面积 户型....

7. 保存数据
8. 多页数据采集

📢爬虫代码

代码部分

import pprint
import requests
import parsel
import csv

f = open('房源.csv', mode='a', encoding='utf-8', newline='')

csv_writer = csv.DictWriter(f, fieldnames=[
    '上次交易',
    '交易权属',
    '产权所属',
    '单价',
    '售价',
    '套内面积',
    '建筑类型',
    '建筑结构',
    '建筑面积',
    '户型结构',
    '房屋年限',
    '房屋户型',
    '房屋朝向',
    '房屋用途',
    '房本备件',
    '房源核验码',
    '所在楼层',
    '抵押信息',
    '挂牌时间',
    '标题',
    '梯户比例',
    '装修情况',
    '详情页',
    '配备电梯',
])
csv_writer.writeheader()
for page in range(1, 11):
    print(f'===================正在爬取第{page}页数据内容===================')

    url = f'https://cs.****.com/ershoufang/pg{page}/'

    headers = {
        'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/97.0.4692.99 Safari/537.36'
    }
    response = requests.get(url=url, headers=headers)

    selector = parsel.Selector(response.text)

    href = selector.css('.sellListContent li .title a::attr(href)').getall()

    for link in href:

        response_1 = requests.get(url=link, headers=headers)

        selector_1 = parsel.Selector(response_1.text)

        title = selector_1.css('.title .main::text').get()
        price = selector_1.css('.price .total::text').get()
        price_1 = selector_1.css('.unitPriceValue::text').get()
        attr_list = selector_1.css('.base .content li .label::text').getall()
        attr_list_1 = selector_1.css('.transaction .content li .label::text').getall()
        content_list = selector_1.css('.base .content li::text').getall()
        content_list_1 = selector_1.css('.transaction .content li span::text').getall()

        dit = {
            "详情页": link,
            "标题": title,
            "售价": price,
            "单价": price_1,

        }
        dit_1 = dict(zip(attr_list, content_list))
        dit_2 = dict(zip(attr_list_1, content_list_1))
        dit.update(dit_1)
        dit.update(dit_2)

        csv_writer.writerow(dit)
        pprint.pprint(dit)

效果展示

部分的数据
表弟准备买房,让我帮他分析分析哪个小区最合适,我直接用python下载了本地所有房源信息做成了可视化图

📢数据分析


import pandas as pd
from pyecharts.charts import Map
from pyecharts.charts import Bar
from pyecharts.charts import Line
from pyecharts.charts import Grid
from pyecharts.charts import Pie
from pyecharts.charts import Scatter
from pyecharts import options as opts

df = pd.read_csv('data.csv', encoding = 'utf-8')
df.head()
df.describe()
df.isnull().sum()
df['电梯'].unique()
df['电梯'].fillna('未知', inplace=True)
df.isnull().sum()
df['电梯'].unique()
df['朝向'].unique()
df['朝向'] = df['朝向'].str.replace('南西','西南')
df['朝向'].unique()

g = df.groupby('市区')
df_region = g.count()['小区']
region = df_region.index.tolist()
count = df_region.values.tolist()
df_region

new = [x + '区' for x in region]
m = (
        Map()
        .add('', [list(z) for z in zip(new, count)], '北京')
        .set_global_opts(
            title_opts=opts.TitleOpts(title='北京市二手房各区分布'),
            visualmap_opts=opts.VisualMapOpts(max_=3000),
        )
    )
m.render_notebook()

df_price = g.mean()['价格(万元)']
df_price

df_price.values.tolist()
price = [round(x,2) for x in df_price.values.tolist()]
bar = (
    Bar()
    .add_xaxis(region)
    .add_yaxis('数量', count,
              label_opts=opts.LabelOpts(is_show=True))
    .extend_axis(
        yaxis=opts.AxisOpts(
            name="价格(万元)",
            type_="value",
            min_=200,
            max_=900,
            interval=100,
            axislabel_opts=opts.LabelOpts(formatter="{value}"),
        )
    )
    .set_global_opts(
        title_opts=opts.TitleOpts(title='各城区二手房数量-平均价格柱状图'),
        tooltip_opts=opts.TooltipOpts(
            is_show=True, trigger="axis", axis_pointer_type="cross"
        ),
        xaxis_opts=opts.AxisOpts(
            type_="category",
            axispointer_opts=opts.AxisPointerOpts(is_show=True, type_="shadow"),
        ),
        yaxis_opts=opts.AxisOpts(name='数量',
            axistick_opts=opts.AxisTickOpts(is_show=True),
            splitline_opts=opts.SplitLineOpts(is_show=False),)
    )
)

line2 = (
    Line()
    .add_xaxis(xaxis_data=region)
    .add_yaxis(

        series_name="价格",
        yaxis_index=1,
        y_axis=price,
        label_opts=opts.LabelOpts(is_show=True),
        z=10
        )
)

bar.overlap(line2)
grid = Grid()
grid.add(bar, opts.GridOpts(pos_left="5%", pos_right="20%"), is_control_axis_index=True)
grid.render_notebook()

top_price = df.sort_values(by="价格(万元)",ascending=False)[:15]
top_price

area0 = top_price['小区'].values.tolist()
count = top_price['价格(万元)'].values.tolist()

bar = (
    Bar()
    .add_xaxis(area0)
    .add_yaxis('数量', count,category_gap = '50%')
    .set_global_opts(
        yaxis_opts=opts.AxisOpts(name='价格(万元)'),
        xaxis_opts=opts.AxisOpts(name='数量'),
    )
)
bar.render_notebook()

s = (
    Scatter()
    .add_xaxis(df['面积(㎡)'].values.tolist())
    .add_yaxis('',df['价格(万元)'].values.tolist())
    .set_global_opts(xaxis_opts=opts.AxisOpts(type_='value'))
)
s.render_notebook()

g = df.groupby('朝向')
g.count()['小区']

df_direction =  g.count()['小区']
df_direction

directions = df_direction.index.tolist()
count = df_direction.values.tolist()

c1 = (
    Pie(init_opts=opts.InitOpts(
            width='800px', height='600px',
            )
       )
        .add(
        '',
        [list(z) for z in zip(directions, count)],
        radius=['20%', '60%'],
        center=['40%', '50%'],

        label_opts=opts.LabelOpts(is_show=True),
        )
        .set_global_opts(title_opts=opts.TitleOpts(title='房屋朝向占比',pos_left='33%',pos_top="5%"),
                        legend_opts=opts.LegendOpts(type_="scroll", pos_left="80%",pos_top="25%",orient="vertical")
                        )
        .set_series_opts(label_opts=opts.LabelOpts(formatter='{b}:{c} ({d}%)'),position="outside")
    )
c1.render_notebook()

g1 = df.groupby('装修情况')
g1.count()['小区']
g2 = df.groupby('电梯')
g2.count()['小区']

df_fitment =  g1.count()['小区']
df_direction =  g2.count()['小区']
df_fitment

fitment = df_fitment.index.tolist()
count1 = df_fitment.values.tolist()

directions = df_direction.index.tolist()
count2 = df_direction.values.tolist()

bar = (
    Bar()
    .add_xaxis(fitment)
    .add_yaxis('', count1, category_gap = '50%')
    .reversal_axis()
    .set_series_opts(label_opts=opts.LabelOpts(position='right'))
    .set_global_opts(
        xaxis_opts=opts.AxisOpts(name='数量'),
        title_opts=opts.TitleOpts(title='装修情况/有无电梯玫瑰图(组合图)',pos_left='33%',pos_top="5%"),
        legend_opts=opts.LegendOpts(type_="scroll", pos_left="90%",pos_top="58%",orient="vertical")
    )
)

c2 = (
    Pie(init_opts=opts.InitOpts(
            width='800px', height='600px',
            )
       )
        .add(
        '',
        [list(z) for z in zip(directions, count2)],
        radius=['10%', '30%'],
        center=['75%', '65%'],
        rosetype="radius",
        label_opts=opts.LabelOpts(is_show=True),
        )
        .set_global_opts(title_opts=opts.TitleOpts(title='有/无电梯',pos_left='33%',pos_top="5%"),
                        legend_opts=opts.LegendOpts(type_="scroll", pos_left="90%",pos_top="15%",orient="vertical")
                        )
        .set_series_opts(label_opts=opts.LabelOpts(formatter='{b}:{c} \n ({d}%)'),position="outside")
    )

bar.overlap(c2)
bar.render_notebook()

g = df.groupby('楼层')
df_floor = g.count()['小区']
df_floor

floor = df_floor.index.tolist()
count = df_floor.values.tolist()
bar = (
    Bar()
    .add_xaxis(floor)
    .add_yaxis('数量', count)
    .set_global_opts(
        title_opts=opts.TitleOpts(title='二手房楼层分布柱状缩放图'),
        yaxis_opts=opts.AxisOpts(name='数量'),
        xaxis_opts=opts.AxisOpts(name='楼层'),
        datazoom_opts=opts.DataZoomOpts(type_='slider')
    )
)
bar.render_notebook()

area_level = [0, 50, 100, 150, 200, 250, 300, 350, 400, 1500]
label_level = ['小于50', '50-100', '100-150', '150-200', '200-250', '250-300', '300-350', '350-400', '大于400']
jzmj_cut = pd.cut(df['面积(㎡)'], area_level, labels=label_level)
df_area = jzmj_cut.value_counts()
df_area

area = df_area.index.tolist()
count = df_area.values.tolist()

bar = (
    Bar()
    .add_xaxis(area)
    .add_yaxis('数量', count)
    .reversal_axis()
    .set_series_opts(label_opts=opts.LabelOpts(position="right"))
    .set_global_opts(
        title_opts=opts.TitleOpts(title='房屋面积分布纵向柱状图'),
        yaxis_opts=opts.AxisOpts(name='面积(㎡)'),
        xaxis_opts=opts.AxisOpts(name='数量'),
    )
)
bar.render_notebook()

效果我就不一一演示了,截图麻烦,可以直接看视频有详细操作~

📢视频讲解

我用python采集了全国的房价数据,发现最近房价都跌的厉害,看看你们那的跌了吗?

有啥问题都欢迎在评论区交流~

Original: https://blog.csdn.net/ooowwq/article/details/122900606
Author: 轻松学Python
Title: 表弟准备买房,让我帮他分析分析哪个小区最合适,我直接用python下载了本地所有房源信息做成了可视化图



相关阅读

Title: einops库中rearrange,reduce和repeat的介绍

用法介绍

einops是一个简洁优雅操作张量的库,并且支持对numpy,pytorch,tensorflow中的张量进行操作,该库最大的优点是函数的使用逻辑清晰明了,其中中常用的三个函数分别是rearrange,repeat,reduce。

  • rearrange: 用于对张量的维度进行重新变换排序,可用于替换pytorch中的reshape,view,transpose和permute等操作
  • repeat: 用于对张量的某一个维度进行复制,可用于替换pytorch中的repeat
  • reduce: 类似于tensorflow中的reduce操作,可以用于求平均值,最大最小值的同时压缩张量维度

einops中rearrange,repeat,reduce的函数细节介绍如下所示

def rearrange(inputs, pattern, **axes_lengths)⟶ \longrightarrow ⟶ transform_inputs

  • inputs (tensor): 表示输入的张量
  • pattern (str): 表示张量维度变换的映射关系
  • axes_lengths**: 表示按照指定的规格形式进行变换

def repeat(inputs, pattern, **axes_lengths)⟶ \longrightarrow ⟶ transform_inputs

  • inputs (tensor): 表示输入的张量
  • pattern (str): 表示张量按照某个维度复制的映射关系
  • axes_lengths**: 表示按照指定的规格形式进行复制

def reduce(inputs, pattern, reduction, **axes_lengths)⟶ \longrightarrow ⟶ transform_inputs

  • inputs (tensor): 表示输入的张量
  • pattern (str): 表示张量执行某种运算做操作后维度变换的映射关系
  • reduction (str): 表示运算操作的类型,分别有'max','min','sum','mean','prod'
  • axes_lengths**: 表示按照指定的规格形式进行运算操作

代码示例

einops库中rearrange函数的代码示例如下所示


>>> images = [np.random.randn(30, 40, 3) for _ in range(32)]

>>> rearrange(images, 'b h w c -> b h w c').shape
(32, 30, 40, 3)

>>> rearrange(images, 'b h w c -> (b h) w c').shape
(960, 40, 3)

>>> rearrange(images, 'b h w c -> h (b w) c').shape
(30, 1280, 3)

>>> rearrange(images, 'b h w c -> b c h w').shape
(32, 3, 30, 40)

>>> rearrange(images, 'b h w c -> b (c h w)').shape
(32, 3600)

>>> rearrange(images, 'b (h1 h) (w1 w) c -> (b h1 w1) h w c', h1=2, w1=2).shape
(128, 15, 20, 3)

>>> rearrange(images, 'b (h h1) (w w1) c -> b h w (c h1 w1)', h1=2, w1=2).shape
(32, 15, 20, 12)

einops库中repeat函数的代码示例如下所示


>>> image = np.random.randn(30, 40)

>>> repeat(image, 'h w -> h w c', c=3).shape
(30, 40, 3)

>>> repeat(image, 'h w -> (repeat h) w', repeat=2).shape
(60, 40)

>>> repeat(image, 'h w -> h (repeat w)', repeat=3).shape
(30, 120)

>>> repeat(image, 'h w -> (h h2) (w w2)', h2=2, w2=2).shape
(60, 80)

>>> downsampled = reduce(image, '(h h2) (w w2) -> h w', 'mean', h2=2, w2=2)
>>> repeat(downsampled, 'h w -> (h h2) (w w2)', h2=2, w2=2).shape
(30, 40)

einops库中reduce函数的代码示例如下所示

>>> x = np.random.randn(100, 32, 64)

>>> y = reduce(x, 't b c -> b c', 'max')

>>> y = reduce(x, 'time batch channel -> batch channel', 'max')
>>> x = np.random.randn(10, 20, 30, 40)

>>> y1 = reduce(x, 'b c (h1 h2) (w1 w2) -> b c h1 w1', 'max', h2=2, w2=2)

>>> y2 = rearrange(y1, 'b (c h2 w2) h1 w1 -> b c (h1 h2) (w1 w2)', h2=2, w2=2)
>>> assert parse_shape(x, 'b _ h w') == parse_shape(y2, 'b _ h w')

>>> reduce(x, 'b c (h1 h2) (w1 w2) -> b c h1 w1', 'max', h1=3, w1=4).shape
(10, 20, 3, 4)

>>> reduce(x, 'b c h w -> b c', 'mean').shape
(10, 20)

>>> y = x - reduce(x, 'b c h w -> () c () ()', 'mean')

>>> y = x - reduce(x, 'b c h w -> b c () ()', 'mean')

Original: https://blog.csdn.net/qq_38406029/article/details/122322166
Author: 鬼道2022
Title: einops库中rearrange,reduce和repeat的介绍

相关文章
JavaCV合并音频到视频封装成MP4 人工智能

JavaCV合并音频到视频封装成MP4

将音频合并到视频有两种情况: 一)音频的播放时长大于视频的播放时长 这种情况相对简单只要在控制音频的播放时长与视频对齐则可,这里主要难点主要在如何使用JavaCV来获取音频时长,代码如下: Strin...
Web开发的分层架构与MVC模式 人工智能

Web开发的分层架构与MVC模式

设计模式(Design Pattern)是前辈们对代码开发经验的总结,代表了最佳的实践是解决特定问题的一系列套路。这些解决方案是众多软件开发人员经过相当长的一段时间的试验和错误总结出来的。它不是语法规...
数学建模之聚类模型 人工智能

数学建模之聚类模型

"物以类聚,人以群分"。包罗万象的数据也是如此,数据本身是凌乱的,如何在凌乱之中去发掘数据的信息呢?本文将介绍聚类模型。 所谓聚类,就是将样本划分为由类似对象组成的多个类的过程。聚类后,我们就可以更加...
谷歌SRE的7条原则 人工智能

谷歌SRE的7条原则

谷歌SRE的7条原则 拥抱合理的风险 最大化系统的稳定性不仅毫无意义,而且会适得其反。不切实际的可靠性目标限制了新功能交付给用户的速度,而且用户通常不会注意到极端的可用性(比如99.99999%),因...