数据清洗 订阅
数据清洗是指发现并纠正数据文件中可识别的错误的最后一道程序,包括检查数据一致性,处理无效值和缺失值等。与问卷审核不同,录入后的数据清理一般是由计算机而不是人工完成。 展开全文
数据清洗是指发现并纠正数据文件中可识别的错误的最后一道程序,包括检查数据一致性,处理无效值和缺失值等。与问卷审核不同,录入后的数据清理一般是由计算机而不是人工完成。
信息
外文名
Data cleaning
对    象
数据
中文名
数据清洗
目    的
发现并纠正数据文件
数据清洗基本概念
数据清洗(Data cleaning)– 对数据进行重新审查和校验的过程,目的在于删除重复信息、纠正存在的错误,并提供数据一致性。数据清洗从名字上也看的出就是把“脏”的“洗掉”,指发现并纠正数据文件中可识别的错误的最后一道程序,包括检查数据一致性,处理无效值和缺失值等。因为数据仓库中的数据是面向某一主题的数据的集合,这些数据从多个业务系统中抽取而来而且包含历史数据,这样就避免不了有的数据是错误数据、有的数据相互之间有冲突,这些错误的或有冲突的数据显然是我们不想要的,称为“脏数据”。我们要按照一定的规则把“脏数据”“洗掉”,这就是数据清洗。而数据清洗的任务是过滤那些不符合要求的数据,将过滤的结果交给业务主管部门,确认是否过滤掉还是由业务单位修正之后再进行抽取。不符合要求的数据主要是有不完整的数据、错误的数据、重复的数据三大类。数据清洗是与问卷审核不同,录入后的数据清理一般是由计算机而不是人工完成 [1]  。一致性检查一致性检查(consistency check)是根据每个变量的合理取值范围和相互关系,检查数据是否合乎要求,发现超出正常范围、逻辑上不合理或者相互矛盾的数据。例如,用1-7级量表测量的变量出现了0值,体重出现了负数,都应视为超出正常值域范围。SPSS、SAS、和Excel等计算机软件都能够根据定义的取值范围,自动识别每个超出范围的变量值。具有逻辑上不一致性的答案可能以多种形式出现:例如,许多调查对象说自己开车上班,又报告没有汽车;或者调查对象报告自己是某品牌的重度购买者和使用者,但同时又在熟悉程度量表上给了很低的分值。发现不一致时,要列出问卷序号、记录序号、变量名称、错误类别等,便于进一步核对和纠正。无效值和缺失值的处理由于调查、编码和录入误差,数据中可能存在一些无效值和缺失值,需要给予适当的处理。常用的处理方法有:估算,整例删除,变量删除和成对删除。估算(estimation)。最简单的办法就是用某个变量的样本均值、中位数或众数代替无效值和缺失值。这种办法简单,但没有充分考虑数据中已有的信息,误差可能较大。另一种办法就是根据调查对象对其他问题的答案,通过变量之间的相关分析或逻辑推论进行估计。例如,某一产品的拥有情况可能与家庭收入有关,可以根据调查对象的家庭收入推算拥有这一产品的可能性。整例删除(casewise deletion)是剔除含有缺失值的样本。由于很多问卷都可能存在缺失值,这种做法的结果可能导致有效样本量大大减少,无法充分利用已经收集到的数据。因此,只适合关键变量缺失,或者含有无效值或缺失值的样本比重很小的情况。变量删除(variable deletion)。如果某一变量的无效值和缺失值很多,而且该变量对于所研究的问题不是特别重要,则可以考虑将该变量删除。这种做法减少了供分析用的变量数目,但没有改变样本量。成对删除(pairwise deletion)是用一个特殊码(通常是9、99、999等)代表无效值和缺失值,同时保留数据集中的全部变量和样本。但是,在具体计算时只采用有完整答案的样本,因而不同的分析因涉及的变量不同,其有效样本量也会有所不同。这是一种保守的处理方法,最大限度地保留了数据集中的可用信息。采用不同的处理方法可能对分析结果产生影响,尤其是当缺失值的出现并非随机且变量之间明显相关时。因此,在调查中应当尽量避免出现无效值和缺失值,保证数据的完整性 [2]  。
收起全文
精华内容
下载资源
问答
  • 数据清洗

    2019-12-11 18:02:33
    数据清洗的概念 数据清洗的流程 字段选择 数据质量报告 数据清洗主要工作 数据清洗的概念 数据清洗主要是针对数据中的错误值、异常值、缺失值进行处理的过程,以及删除那些取值很多的类别型字段,或者取值一致性...

    数据清洗的概念

    数据清洗的流程

    字段选择

    数据质量报告

    数据清洗主要工作

    数据清洗的概念

    数据清洗主要是针对数据中的错误值、异常值、缺失值进行处理的过程,以及删除那些取值很多的类别型字段,或者取值一致性程度极高的字段。

    数据清洗流程

    1.再次确认数据是否拷贝

    2.再次确认原始数据中是否具有唯一ID

    3.清洗数据中错误值(填写错误、逻辑错误)

    4.清洗数据中的异常值

    5.清洗数据中的缺失值

    字段选择

    通常在收集的原始数据中,**将姓名或其他字符串的字段不选入最终分析的数据库中,**如问卷调查中的主观开放题。
    在实际项目中,如果客户有历史数据,应提取越多字段的数据越好。
    另外,需处理数据整合的问题,如数据单位不一致问题(美元*人民币)、数据重复问题(A和B数据库中都存在一部分重复用户的数据,合并时需剔除)。
    字段数据重复:单个字段数据重复、多个字段之间的数据重复

    数据清洗主要工作

    噪声消除

    噪声包括错误值(以类别字段为主)和异常值(针对变量)
    噪声会使后期分析结果产生很大偏差,必须对噪声进行有效的识别和处理

    缺失值处理

    • 人工处理
    • 软件自动处理

    错误值和异常值处理方法**

    软件及人工结合的方法

    错误值:
    无论分类变量还是连续变量,均先检查数据的分布情况,找到错误值。对于分类变量,检查与其他值是否有相似之处,如无,直接处理空值/未知。

    异常值:
    判断标准:1)最小最大分布法,按从小到大排序,选取最小的5%和最大的95%数据作为异常值;
    2)标准分法:平均±3个标准差(1个标准差:68%;2个标准差:95%;3个标准差:99.7%,6 σ:99.9996%)
    3)四分位数法:IQR=Q3-Q1,Q1-1.5*IQR~Q3+1.5/*IQR

    异常值处理方法:
    1)直接视为空值
    2)最大、最小、均值代替
    3)函数校正法:如回归、决策数等

    缺失值处理方法

    1.直接忽略法

    适合的场景:
    1)数据样本量很多时,且包含缺失值的样本数较少时;
    2)该样本缺失的字段占总字段一半以上时,可直接删除该样本;
    3)在进行分类统计时,如果该样本分类标记为空值,因为该样本无法被归类,可直接删除,尤其是该分类变量是模型分析的关键变量,如是否死亡。

    缺点:
    方法太过于简单粗暴,当缺失值现象较多时,直接删除会造成大量信息丢失,甚至让整个项目无法进行下去。

    2.将缺失值所在字段处理为指示变量

    当该字段在所有样本中,有一半以上样本都存在缺失现象时,可将该字段作为指示变量,变量值为:缺失和未缺失

    3.人工补充法

    适合的场景:
    1)缺少较少时,可通过人工从原始数据库再次查询或调查,如让客户再调用底层数据补充缺失的字段,以及人工电话再联络该样本再次询问缺失字段的选项;
    2)通过其他数据计算得到,如性别、年龄、省份等字段可通过身份证号获取。

    缺点:当缺失值现象较多时,人工成本较高,实际操作压力较大。

    4.自动填补法

    针对分类变量:
    1)以通用的常数值代替,如“未知/缺失”;
    2)填入该字段的众数;
    3)用其他一个或多个字段预测该缺失值,如收入阶层可通过学历、年龄预测得到。

    针对连续变量:
    1)填入该字段的众数;
    2)均值:所有样本的均值、附近样本的均值;
    3)中位值:所有样本的均值、附近样本的中位数;
    4)模型预测:通过其他字段与该字段建立模型,预测该缺失字段。

    展开全文
  • 【项目实战】数据爬虫 + 数据清洗 + 数据可视化

    万次阅读 多人点赞 2020-05-11 10:37:08
    自己亲手全手打了一套系统的代码,帮助朋友完成设计,做了贵阳市几个区的房屋价格爬取以及数据清洗和可视化操作,代码细细道来: 上图镇楼,接下来细说。 一:数据挖掘 我选用了链家网做数据爬取场所(不得不唠叨...

    自定义的文章目录

    最新更新(代码开源啦)

    写在前面:

    自己的公众号:DeepAI 视界
    免费将自己见过,做过的优质数据集分享给大家
    有大量标注好的数据 ,敬请大家关注~

    以及各种开源算法分享给大家
    在这里插入图片描述

    自己亲手全手打了一套系统的代码,帮助朋友完成设计,做了贵阳市几个区的房屋价格爬取以及数据清洗和可视化操作,代码细细道来:

    [外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-CKhdmiWg-1589163973193)(D:\CSDN\pic\爬虫毕设_买房\8dd4fd69b590a25bd4427de2020a559.png)]

    上图镇楼,接下来细说。


    一:数据挖掘

    我选用了链家网做数据爬取场所(不得不唠叨一句,这个网站真是为了爬虫而生的,对爬虫特别友好哈哈哈,反扒措施比较少)

    比如我们爬取贵阳市乌当区的所有房子的房价及其他信息:
    [外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-55GwXGeD-1589163973196)(D:\CSDN\pic\爬虫毕设_买房\1589118368542.png)]

    比如我们爬取第一个房子的价格:115万:
    [外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-xyKYNu5z-1589163973199)(D:\CSDN\pic\爬虫毕设_买房\1589119934247.png)]

    接下来我们可以使用复制CSS选择器或者XPath等等来实现获取:

    [外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-iNZbnpRE-1589163973204)(D:\CSDN\pic\爬虫毕设_买房\1589120121369.png)]

    下面我们使用复制XPath的方式,修改路径即可(需要一定前端知识)

    分别实现详解:

    1:导入必备库

    import requests
    from lxml import etree
    import xlwt
    from xlutils.copy import copy
    import xlrd
    import csv
    import pandas as pd
    import time
    

    细说一下:
    Requests 是用Python语言编写,基于 urllib,采用 Apache2 Licensed 开源协议的 HTTP 库,爬虫必备技能之一。它比 urllib 更加方便,可以节约我们大量的工作,完全满足 HTTP 测试需求。Requests 的哲学是以 PEP 20 的习语为中心开发的,所以它比 urllib 更加 Pythoner。更重要的一点是它支持 Python3 哦!

    Pandas是python第三方库,提供高性能易用数据类型和分析工具 , pandas是一个强大的分析结构化数据的工具集;它的使用基础是Numpy(提供高性能的矩阵运算);用于数据挖掘和数据分析,同时也提供数据清洗功能。

    2:定义爬取URL地址和设置请求头(其实还可以更完善,不过链家网比较友善,这点够用了)

            self.url = 'https://gy.lianjia.com/ershoufang/wudangqu/pg{}/'
            self.headers = {
                "User-Agent": "Mozilla/5.0 (Windows NT 10.0; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/75.0.3770.100 Safari/537.36"}
    
    

    url是要获取信息的地址:我们选用贵阳市(gy)乌当区(wudangqu)为目标,然后pg{}是页码的意思:pg100就是爬第一百页,这里我们使用{}做一下占位,方便后续从第一页迭代到最后。

    headers是我们的请求头,就是模拟人正常登录的意思,而不是通过python,让网页知道你是爬虫,知道了就有可能封掉你的IP等。 通常HTTP消息包括客户机向服务器的请求消息和服务器向客户机的响应消息。这两种类型的消息由一个起始行,一个或者多个头域,一个只是头域结束的空行和可 选的消息体组成。HTTP的头域包括通用头,请求头,响应头和实体头四个部分。每个头域由一个域名,冒号(:)和域值三部分组成。域名是大小写无关的,域 值前可以添加任何数量的空格符,头域可以被扩展为多行,在每行开始处,使用至少一个空格或制表符。 User-Agent头域的内容包含发出请求的用户信息。

    3:使用Requests获取数据

        def get_response_spider(self, url_str):  # 发送请求
            get_response = requests.get(self.url, headers=self.headers)
            time.sleep(4)
            response = get_response.content.decode()
            html = etree.HTML(response)
            return html
    

    4:使用Xpath筛选数据源,过程见上图,需要一定的前端知识,不过,也有一些技巧:

        def get_content_html(self, html):  # 使xpath获取数据
            self.houseInfo = html.xpath('//div[@class="houseInfo"]/text()')
            self.title = html.xpath('//div[@class="title"]/a/text()')
            self.positionInfo = html.xpath('//div[@class="positionInfo"]/a/text()')
            self.totalPrice = html.xpath('//div[@class="totalPrice"]/span/text()')
            self.unitPrice = html.xpath('//div[@class="unitPrice"]/span/text()')
            self.followInfo = html.xpath('//div[@class="followInfo"]/text()')
            self.tag = html.xpath('//div[@class="tag"]/span/text()')
    

    5:使用生成器,通过for循环和yield生成器迭代生成数据项:

        def xpath_title(self):
            for i in range(len(self.title)):
                yield self.title[i]
    
        def xpath_positionInfo(self):
            for i in range(len(self.positionInfo)):
                yield self.positionInfo[i]
    
        def xpath_totalPrice(self):
            for i in range(len(self.totalPrice)):
                yield self.totalPrice[i]
        def xpath_unitPrice(self):
            for i in range(len(self.unitPrice)):
                yield self.unitPrice[i]
        def xpath_followInfo(self):
            for i in range(len(self.followInfo)):
                yield self.followInfo[i]
        def xpath_tag(self):
            for i in range(len(self.tag)):
                yield self.tag[i]
    

    6:通过调用这些函数进行预获得:

    self.xpath_houseInfo()
            self.xpath_title()
            self.xpath_positionInfo()
            self.xpath_totalPrice()
            self.xpath_unitPrice()
            self.xpath_followInfo()
            self.xpath_tag()
            get_houseInfo = self.xpath_houseInfo()
            get_title = self.xpath_title()
            get_positionInfo=self.xpath_positionInfo()
            get_totalPrice = self.xpath_totalPrice()
            get_unitPrice = self.xpath_unitPrice()
            get_followInfo=self.xpath_followInfo()
            get_tag=self.xpath_tag()
    

    这里的函数就是调用上面的生成器的函数:
    生成器yield 理解的关键在于:下次迭代时,代码从yield的下一跳语句开始执行。

    7:数据筛选,写入文本中:

            while True:
                data_houseInfo= next(get_houseInfo)
                data_title=next(get_title)
                data_positionInfo=next(get_positionInfo)
                data_totalPrice=next(get_totalPrice)
                data_unitPrice=next(get_unitPrice)
                data_followInfo=next(get_followInfo)
                data_tag=next(get_tag)
    
                with open("lianjia1.csv", "a", newline="", encoding="utf-8-sig") as f:
                    fieldnames = ['houseInfo', 'title', 'positionInfo', 'totalPrice/万元', 'unitPrice', 'followInfo', 'tag']
                    writer = csv.DictWriter(f, fieldnames=fieldnames)  # 写入表头
                    writer.writeheader()
                    list_1 = ['houseInfo', 'title', 'positionInfo', 'totalPrice/万元', 'unitPrice', 'followInfo', 'tag']
                    list_2 = [data_houseInfo,data_title,data_positionInfo,data_totalPrice,data_unitPrice,data_followInfo,data_tag]
                    list_3 = dict(zip(list_1, list_2))
                    writer.writerow(list_3)
                    print("写入第"+str(i)+"行数据")
                i += 1
                if i > len(self.houseInfo):
                    break
    

    8:这里用过Next方法对生成器中内容不断提取:

    fieldnames = ['houseInfo', 'title', 'positionInfo', 'totalPrice/万元', 'unitPrice', 'followInfo', 'tag']
    writer = csv.DictWriter(f, fieldnames=fieldnames)  # 写入表头
    writer.writeheader()
    

    9:将其加在表头中。然后每一行写入一次数据

    10:最后构造run函数:

        def run(self):
            i = 1
            while True:
                url_str = self.url.format(i)  # 构造请求url
                html = self.get_response_spider(url_str)
                self.get_content_html(html)
                self.qingxi_data_houseInfo()
    
                i += 1
                if i == 57:  
                    break
    

    11:循环迭代一下,将上述的page页码从一到最后

    12:main函数中启动一下,先new一下这个类,再启动run函数,就会开始爬取了

    [外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-YpDU0UZV-1589163973208)(D:\CSDN\pic\爬虫毕设_买房\1589157338385.png)]

    然后我们看一下结果:

    [外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-MdzDg69f-1589163973209)(D:\CSDN\pic\爬虫毕设_买房\1589157875463.png)]

    然后爬虫阶段就结束了,当然也可以写入数据库中,我们保存在文本文件中是为了更方便。我们保存在了左边的csv文件中,是不是很简单~,源码这个网上应该也有,我就暂时不放了,等朋友毕业再发


    二:数据清洗与提取

    1:首先导入一下需要的库

    """
    数据分析及可视化
    """
    import pandas as pd
    from pyecharts.charts import Line, Bar
    import numpy as np
    from pyecharts.globals import ThemeType
    from pyecharts.charts import Pie
    from pyecharts import options as opts
    

    2:数据全局定义:

    places = ['lianjia_BaiYunQu', 'lianjia_GuanShanHuQu', 'lianjia_HuaXiQu', 'lianjia_NanMingQu', 'lianjia_WuDangQu', 'lianjia_YunYanQu']
    place = ['白云区', '观山湖区', '花溪区', '南明区', '乌当区', '云岩区']
    avgs = []  # 房价均值
    median = []  # 房价中位数
    favourate_avg = []  # 房价收藏人数均值
    favourate_median = []  # 房价收藏人数中位数
    houseidfo = ['2室1厅', '3室1厅', '2室2厅', '3室2厅', '其他']  # 房型定义
    houseidfos = ['2.1', '3.1', '2.2', '3.2']  
    sum_house = [0,  0, 0, 0, 0]  # 各房型数量
    price = []  # 房价
    fav = []  # 收藏人数
    type = []  
    area = []  # 房间面积
    

    注释写的很清楚了,我的places是为了方便读取这几个csv中文件各自保存的数据(‘白云区’, ‘观山湖区’, ‘花溪区’, ‘南明区’, ‘乌当区’, '云岩区’区的数据):
    [外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-PSolJZcb-1589163973212)(D:\CSDN\pic\爬虫毕设_买房\1589158268089.png)]

    3:文件操作,打开文件:

    def avg(name):
    	df = pd.read_csv(str(name)+'.csv', encoding='utf-8')
        pattern = '\d+'
        df['totalPrice/万元'] = df['totalPrice/万元'].str.findall(pattern) # 转换成字符串,并且查找只含数字的项
        df['followInfo'] = df['followInfo'].str.findall(pattern)
        df['houseInfo'] = df['houseInfo'].str.findall(pattern)
    

    使用padas的read_csv方式读取csv文件 name以传参形式迭代传入,也就是一个区一个区的传入主要是为了减少代码量,增加审美。就不必每一次都写几十行代码了

    然后是一些匹配,转换成字符串,并且查找只含数字的项。

        for i in range(len(df)):
            if (i + 1) % 2 == 0:
                continue
            else:
                if len(df['totalPrice/万元'][i]) == 2:
                    avg_work_year.append(','.join(df['totalPrice/万元'][i]).replace(',', '.'))
                    medians.append(float(','.join(df['totalPrice/万元'][i]).replace(',', '.')))
                    price.append(','.join(df['totalPrice/万元'][i]).replace(',', '.'))
                if len(df['followInfo'][i]) ==2:
                    favourates.append(int(','.join(df['followInfo'][i][:1])))
                    fav.append(int(','.join(df['followInfo'][i][:1])))
                if float(','.join(df['houseInfo'][i][:2]).replace(',', '.')) == 2.1:
                    k +=1
                    sum_houses[0] =k
                    type.append(2.1)
                if float(','.join(df['houseInfo'][i][:2]).replace(',', '.')) == 3.1:
                    k1 +=1
                    sum_houses[1] =k1
                    type.append(3.1)
                if float(','.join(df['houseInfo'][i][:2]).replace(',', '.')) == 2.2:
                    k3 +=1
                    sum_houses[2] =k3
                    type.append(2.2)
                if float(','.join(df['houseInfo'][i][:2]).replace(',', '.')) == 3.2:
                    k4 +=1
                    sum_houses[3] =k4
                    type.append(3.2)
                else:
                    k4 +=1
                    sum_houses[4] = k4
                    type.append('other')
                area.append(float(','.join(df['houseInfo'][i][2:4]).replace(',', '.')))
        sum_house[0] =sum_houses[0]
        sum_house[1] = sum_houses[1]
        sum_house[2] = sum_houses[2]
        sum_house[3] = sum_houses[3]
        sum_house[4] = sum_houses[4]
    
        favourates.sort()
        favourate_median.append(int(np.median(favourates)))
        medians.sort()
        median.append(np.median(medians))
        # price = avg_work_year
        b = len(avg_work_year)
        b1= len(favourates)
    
        sum = 0
        sum1 = 0
        for i in avg_work_year:
            sum = sum+float(i)
        avgs.append(round(sum/b, 2))
        for i in favourates:
            sum1 = sum1+float(i)
        favourate_avg.append(round(int(sum1/b1), 2))
    
    

    4:这里是数据筛选的核心部分,我们细说一下:

    		if len(df['totalPrice/万元'][i]) == 2:
                    avg_work_year.append(','.join(df['totalPrice/万元'][i]).replace(',', '.'))
                    medians.append(float(','.join(df['totalPrice/万元'][i]).replace(',', '.')))
                    price.append(','.join(df['totalPrice/万元'][i]).replace(',', '.'))
    

    5:这里是获取总价格,并且清洗好,放入前面定义好的数组中,保存好,

    if len(df['followInfo'][i]) ==2:
                    favourates.append(int(','.join(df['followInfo'][i][:1])))
                    fav.append(int(','.join(df['followInfo'][i][:1])))
    

    6:这里是获取总收藏人数,并且清洗好,放入前面定义好的数组中,保存好,

    if len(df['followInfo'][i]) ==2:
                    favourates.append(int(','.join(df['followInfo'][i][:1])))
                    fav.append(int(','.join(df['followInfo'][i][:1])))
                if float(','.join(df['houseInfo'][i][:2]).replace(',', '.')) == 2.1:
                    k +=1
                    sum_houses[0] =k
                    type.append(2.1)
                if float(','.join(df['houseInfo'][i][:2]).replace(',', '.')) == 3.1:
                    k1 +=1
                    sum_houses[1] =k1
                    type.append(3.1)
                if float(','.join(df['houseInfo'][i][:2]).replace(',', '.')) == 2.2:
                    k3 +=1
                    sum_houses[2] =k3
                    type.append(2.2)
                if float(','.join(df['houseInfo'][i][:2]).replace(',', '.')) == 3.2:
                    k4 +=1
                    sum_houses[3] =k4
                    type.append(3.2)
                else:
                    k4 +=1
                    sum_houses[4] = k4
                    type.append('other')
                area.append(float(','.join(df['houseInfo'][i][2:4]).replace(',', '.')))
    

    7:这里是获取房型和面积,清洗好,放入数组中

        favourates.sort()
        favourate_median.append(int(np.median(favourates)))
        medians.sort()
        median.append(np.median(medians))
        # price = avg_work_year
        b = len(avg_work_year)
        b1= len(favourates)
    
        sum = 0
        sum1 = 0
        for i in avg_work_year:
            sum = sum+float(i)
        avgs.append(round(sum/b, 2))
        for i in favourates:
            sum1 = sum1+float(i)
        favourate_avg.append(round(int(sum1/b1), 2))
    

    8:这里是把上面的信息加工,生成平均数,中位数等。

    另外说一下,清洗过程:
    ’,’.join()是为了筛选出的信息不含中括号和逗号

    df[‘houseInfo’][i][2:4]是为了取出相应的数据,使用了python的切片操作

    .replace(’,’, ‘.’)是把逗号改成小数点,这样就是我们想要的结果了。

    下面执行看一下结果:
    [外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-IgXgGFDW-1589163973214)(D:\CSDN\pic\爬虫毕设_买房\1589159955086.png)]

    数据筛选结束~


    三、数据可视化

    python的数据可视化操作很完善,还很多样,我们先来看看几种常用的:

    • Matplotlib:基于Python的绘图库,提供完全的 2D 支持和部分 3D 图像支持。在跨平台和互动式环境中生成高质量数据时,matplotlib 会很有帮助。也可以用作制作动画。
    • Seaborn:该 Python 库能够创建富含信息量和美观的统计图形。Seaborn 基于 matplotlib,具有多种特性,比如内置主题、调色板、可以可视化单变量数据、双变量数据,线性回归数据和数据矩阵以及统计型时序数据等,能让我们创建复杂的可视化图形。

    我们今天提供一个更美观,更方便的数据可视化库:Pyecahrts

    1:首先绘制一下地区与房价关系折线图:

    line = Line()
    line.add_xaxis(place)
    line.add_yaxis("贵阳各地房价平均值(万元)", avgs)
    line.add_yaxis("贵阳各地房价中位数值(万元)", median)
    line.render("predict_line.html")
    
    

    x轴放入我们的place地区,y轴放入房价平均值和中位数值,就这几行代码,有木有很舒服。这时,执行一下,就会在当前目录生成predict_line.html,我们点开看一下

    ​	[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-HSdtoFU7-1589163973216)(D:\CSDN\pic\爬虫毕设_买房\1589160609873.png)]

    这是html网页代码,会支持在本地局域网打开我们点击一下右上角的浏览器,就可以看到:
    [外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-sQlQWykj-1589163973218)(D:\CSDN\pic\爬虫毕设_买房\1589160666559.png)]

    分析一下:
    折线图直观明了地告诉了我们以下信息:
    在这六个区中乌当区的平均房价和中位数远低于其他几个区,其中花溪区和云岩区以及南明区不相上平均房价为79万左右,说明这两地的经济水平,购房水平比较相似。乌当区经济水平和居民购房能力较弱。

    2:绘制上述的柱状图

    def bar() -> Bar:
        c = (
            Bar({"theme": ThemeType.MACARONS})
                .add_xaxis(place)
                .add_yaxis("平均值", avgs)
                .add_yaxis("中位数", median)
                .set_global_opts(
                title_opts={"text": "贵阳各地房价(万元)"}
            )
        )
        return c
    bar().render("predict_bar.html")
    

    同样的方式查看一下:
    [外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-O37wVxAL-1589163973219)(D:\CSDN\pic\爬虫毕设_买房\1589162000990.png)]

    3:绘制各区房型与数量的关系柱状图:

    def bar() -> Bar:
        c = (
            Bar({"theme": ThemeType.MACARONS})
                .add_xaxis(houseidfo)
                .add_yaxis(place[0], [280, 56, 504, 1676, 1680])
                .add_yaxis(place[1], [392, 112, 448, 1679, 1680])
                .add_yaxis(place[2], [224, 0, 616, 3359, 3360])
                .add_yaxis(place[3], [448, 112, 280, 1679, 1680])
                .add_yaxis(place[4], [504, 0, 336, 1680, 1679])
                .add_yaxis(place[-1], sum_house)
                # .add_yaxis("中位数", favourate_median)
                .set_global_opts(
                title_opts={"text": "贵阳各地房型\n数量"}
            )
        )
        return c
    bar().render("house_bar.html")
    

    查看一下:

    [外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-xFyeOBGS-1589163973222)(D:\CSDN\pic\爬虫毕设_买房\1589162145051.png)]

    可以看到各区普遍是三室两厅和其他房型较多,其中花溪区的三室两厅远超平均水平,其他区比较持平。

    4:绘制各区平均房间收藏人数和中位数饼状图

    list_num = favourate_avg
    attr = place
    # print(zip(attr, list_num))
    s = [list(z) for z in zip(attr, list_num)]
    c = (Pie().add("", s).set_global_opts(title_opts=opts.TitleOpts(title="贵阳市各区楼房\n平均收藏人数"))
         .set_series_opts(label_opts=opts.LabelOpts(formatter="{b}: {c}"))
         )
    c.render("pie_avg.html")
    
    list_num = favourate_median
    attr = place
    # print(zip(attr, list_num))
    s = [list(z) for z in zip(attr, list_num)]
    c = (Pie().add("", s).set_global_opts(title_opts=opts.TitleOpts(title="贵阳市各区楼房\n收藏人数中位数"))
         .set_series_opts(label_opts=opts.LabelOpts(formatter="{b}: {c}"))
         )
    c.render("pie_median.html")
    

    看效果:
    ![[外链图片转存失败,源站可能有防10,text_aHR0cHM6Ly9ibG9nLmNzZG4ubmV0L3FxXzQ2MDk4NTc0,size_16,color_FFFFFF,t_70)

    [外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-h5s1DJMJ-1589163973226)(D:\CSDN\pic\爬虫毕设_买房\1589163186035.png)]

    5:绘制贵阳各地房子平均面积\n(平米)折线图

    line = Line()
    line.add_xaxis(place)
    line.add_yaxis("贵阳各地房子平均面积\n(平米)", area)
    line.render("Area_line.html")
    

    [外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-g9lDNV3S-1589163973227)(D:\CSDN\pic\爬虫毕设_买房\1589162739501.png)]

    可以看到南明区的房间的平均面积最大,观山湖区最小,右上可以看出,南明区的房价又高,面积又大不过收藏人数缺平均最低,可见可能由于郊区等原因,购房群体较少

    6:绘制房型和用户收藏人数和房间价格三维立体散点图

    from pyecharts import options as  opts
    from pyecharts.charts import Scatter3D
    from pyecharts.faker import Faker
    
    
    price=[float(i)/1 for i in price]
    # print(price)
    # types=list(map(mapfunc,df.house_type.values))
    # type = [224, 56, 168, 1680, 1670]
    data = []
    # print(fav,type)
    # for j in range(len(type)):
    #     for k in range(len(fav)):
    for j in range(100):
        for k in range(100):
            for i in range(500):
                try:
                    data.append([type[j], favourate_avg[k],price[i]])
                except:
                    continue
    # print(data)
    scatter = (
         Scatter3D(init_opts=opts.InitOpts(width='900px', height='600px'))  # 初始化
              .add("", data,
                   grid3d_opts=opts.Grid3DOpts(
                        width=300, depth=300, rotate_speed=300, is_rotate=True,
                   ),)
    
              # 设置全局配置项
              .set_global_opts(
              title_opts=opts.TitleOpts(title="房型——关注度——价格\n三维关系图"),  # 添加标题
              visualmap_opts=opts.VisualMapOpts(
                   max_=100,  # 最大值
                   pos_top=200,  # visualMap 组件离容器上侧的距离
                   range_color=Faker.visual_color  # 颜色映射
              )
         )
              # .render("3D散点图.html")
    )
    print('数据分析和可视化结束,左边点开~')
    

    可看到:

    [外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-zPkmwOSd-1589163973230)(D:\CSDN\pic\爬虫毕设_买房\1589163435450.png)]

    说明房型为三室两厅的情况下,用户的收藏喜爱程度和价格都可关,人们普遍喜欢80万左右的三室两厅房子。


    最后总结一下:

    我们通过爬取网站中贵阳市的6个区的房价,做了数据分析,并可视化呈现出来,为了更直观的感受到,各个维度之间的影响(见上)。完善的实验,可以成为有利的论据,今天的分享到此结束。感谢~

    最后请务必关注一下博主,码字不易~

    附上源码之前,关注一下公众号~
    在这里插入图片描述 展示一下:
    [外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-NHjiiMWw-1594978846603)(D:\CSDN\pic\爬虫毕设_买房\1590669460346.png)]

    在这里插入图片描述
    在这里插入图片描述
    在这里插入图片描述
    在这里插入图片描述
    在这里插入图片描述
    在这里插入图片描述

    [外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-jPvdM9va-1594978846610)(D:\CSDN\pic\爬虫毕设_买房\1590669524605.png)]

    爬虫:链接网二手房(以贵阳市为例)

    """
    爬虫
    """
    import requests
    from lxml import etree
    import xlwt
    import xlrd
    import csv
    import pandas as pd
    import time
    import re
    class LanjiaSpider:
        def __init__(self):
            self.url = 'https://wh.lianjia.com/ershoufang/ronganxian/pg{}/'
            self.headers = {
                "User-Agent": "Mozilla/5.0 (Windows NT 10.0; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/75.0.3770.100 Safari/537.36"}
    
        def get_response_spider(self, url_str):  # 发送请求
            get_response = requests.get(self.url, headers=self.headers)
            time.sleep(2)
            response = get_response.content.decode()
            html = etree.HTML(response)
            return html
        def get_content_html(self, html):  # 使xpath获取数据
            self.houseInfo = html.xpath('//div[@class="houseInfo"]/text()')
            self.title = html.xpath('//div[@class="title"]/a/text()')
            self.positionInfo = html.xpath('//div[@class="positionInfo"]/a/text()')
            self.totalPrice = html.xpath('//div[@class="totalPrice"]/span/text()')
            self.unitPrice = html.xpath('//div[@class="unitPrice"]/span/text()')
            self.followInfo = html.xpath('//div[@class="followInfo"]/text()')
            self.tag = html.xpath('//div[@class="tag"]/span/text()')
            # print(title)
            # return houseInfo,title,positionInfo,totalPrice,unitPrice,followInfo,tag
    
        def xpath_houseInfo(self):
            #print(self.houseInfo)
            #print(type(self.houseInfo))
            # df = pd.DataFrame({"houseInfo": self.houseInfo,"tite":self.title,"positionInfo":self.positionInfo,"totaPrice":self.totalPrice,"unitPrice":self.unitPrice,"followInfo":self.followInfo,"tag":self.tag})
            # df=pd.DataFrame({"houseInfo": self.houseInfo,"tite":self.title})
            # df.to_excel(r'C:\Users\wy\Desktop\sublime\链家\pand3.xlsx')
            # a=len(self.houseInfo)
            for i in range(len(self.houseInfo)):
                # print(i)
                # yield i
                # print(type(self.houseInfo))
                yield self.houseInfo[i]
    
        def qingxi_data_houseInfo(self):  # 清洗数据
    
            self.xpath_houseInfo()
            self.xpath_title()
            self.xpath_positionInfo()
            self.xpath_totalPrice()
            self.xpath_unitPrice()
            self.xpath_followInfo()
            self.xpath_tag()
            get_houseInfo = self.xpath_houseInfo()
            get_title = self.xpath_title()
            get_positionInfo=self.xpath_positionInfo()
            get_totalPrice = self.xpath_totalPrice()
            get_unitPrice = self.xpath_unitPrice()
            get_followInfo=self.xpath_followInfo()
            get_tag=self.xpath_tag()
            i = 1
    
            while True:
                data_houseInfo= next(get_houseInfo)
                data_title=next(get_title)
                data_positionInfo=next(get_positionInfo)
                data_totalPrice=next(get_totalPrice)
                data_unitPrice=next(get_unitPrice)
                data_followInfo=next(get_followInfo)
                data_tag=next(get_tag)
    
                with open("a.csv", "a", newline="", encoding="utf-8-sig") as f:
                    # fieldnames = ['houseInfo', 'title', 'positionInfo', 'totalPrice/万元', 'unitPrice', 'followInfo', 'tag']
                    # writer = csv.DictWriter(f, fieldnames=fieldnames)  # 写入表头
                    # writer.writeheader()
                    writer = csv.DictWriter(f, fieldnames=fieldnames)  # 写入表头
    
                    list_1 = ['houseInfo', 'title', 'positionInfo', 'totalPrice/万元', 'unitPrice', 'followInfo', 'tag']
                    list_2 = [data_houseInfo,data_title,data_positionInfo,data_totalPrice,data_unitPrice,data_followInfo,data_tag]
                    list_3 = dict(zip(list_1, list_2))
                    writer.writerow(list_3)
                    print("写入第"+str(i)+"行数据")
                i += 1
                if i > len(self.houseInfo):
                    break
    
        def xpath_title(self):
            for i in range(len(self.title)):
                yield self.title[i]
    
        def xpath_positionInfo(self):
            for i in range(len(self.positionInfo)):
                yield self.positionInfo[i]
    
        def xpath_totalPrice(self):
            for i in range(len(self.totalPrice)):
                yield self.totalPrice[i]
        def xpath_unitPrice(self):
            for i in range(len(self.unitPrice)):
                yield self.unitPrice[i]
        def xpath_followInfo(self):
            for i in range(len(self.followInfo)):
                yield self.followInfo[i]
        def xpath_tag(self):
            for i in range(len(self.tag)):
                yield self.tag[i]
        def run(self):
            i = 1
            while True:
                url_str = self.url.format(i)  # 构造请求url
                html = self.get_response_spider(url_str)
                self.get_content_html(html)
                self.qingxi_data_houseInfo()
    
                i += 1
                if i == 1:  # 不包括57页
                    break
    
    
    if __name__ == "__main__":
        with open("a.csv", "a", newline="", encoding="utf-8-sig") as f:
            fieldnames = ['houseInfo', 'title', 'positionInfo', 'totalPrice/万元', 'unitPrice', 'followInfo', 'tag']
            writer = csv.DictWriter(f, fieldnames=fieldnames)  # 写入表头
            writer.writeheader()
        lanjia = LanjiaSpider()
        lanjia.run()
    
    

    对应的数据可视化:

    """
    数据分析及可视化
    """
    import pandas as pd
    from pyecharts.charts import Line, Bar
    import numpy as np
    from pyecharts.globals import ThemeType
    from pyecharts.charts import Pie
    from pyecharts import options as opts
    
    
    places = ['lianjia_BaiYunQu', 'lianjia_GuanShanHuQu', 'lianjia_HuaXiQu', 'lianjia_NanMingQu', 'lianjia_WuDangQu', 'lianjia_YunYanQu']
    place = ['白云区', '观山湖区', '花溪区', '南明区', '乌当区', '云岩区']
    avgs = []  # 房价均值
    median = []  # 房价中位数
    favourate_avg = []  # 房价收藏人数均值
    favourate_median = []  # 房价收藏人数中位数
    houseidfo = ['2室1厅', '3室1厅', '2室2厅', '3室2厅', '其他']  # 房型定义
    houseidfos = ['2.1', '3.1', '2.2', '3.2']
    sum_house = [0,  0, 0, 0, 0]  # 各房型数量
    price = []  # 房价
    fav = []  # 收藏人数
    type = []
    area = []  # 房间面积
    def avg(name):
        df = pd.read_csv(str(name)+'.csv', encoding='utf-8')
        pattern = '\d+'
        df['totalPrice/万元'] = df['totalPrice/万元'].str.findall(pattern)
        df['followInfo'] = df['followInfo'].str.findall(pattern)
        df['houseInfo'] = df['houseInfo'].str.findall(pattern)
        sum_houses = [0, 0, 0, 0, 0]
        # print(sum_house)
        avg_work_year = []
        medians = []
        favourates = []
        k = 0
        k1 = 0
        k3 = 0
        k4 = 0
    
        for i in range(len(df)):
            if (i + 1) % 2 == 0:
                continue
            else:
                if len(df['totalPrice/万元'][i]) == 2:
                    avg_work_year.append(','.join(df['totalPrice/万元'][i]).replace(',', '.'))
                    medians.append(float(','.join(df['totalPrice/万元'][i]).replace(',', '.')))
                    price.append(','.join(df['totalPrice/万元'][i]).replace(',', '.'))
                if len(df['followInfo'][i]) ==2:
                    favourates.append(int(','.join(df['followInfo'][i][:1])))
                    fav.append(int(','.join(df['followInfo'][i][:1])))
                if float(','.join(df['houseInfo'][i][:2]).replace(',', '.')) == 2.1:
                    k +=1
                    sum_houses[0] =k
                    type.append(2.1)
                if float(','.join(df['houseInfo'][i][:2]).replace(',', '.')) == 3.1:
                    k1 +=1
                    sum_houses[1] =k1
                    type.append(3.1)
                if float(','.join(df['houseInfo'][i][:2]).replace(',', '.')) == 2.2:
                    k3 +=1
                    sum_houses[2] =k3
                    type.append(2.2)
                if float(','.join(df['houseInfo'][i][:2]).replace(',', '.')) == 3.2:
                    k4 +=1
                    sum_houses[3] =k4
                    type.append(3.2)
                else:
                    k4 +=1
                    sum_houses[4] = k4
                    type.append('other')
                area.append(float(','.join(df['houseInfo'][i][2:4]).replace(',', '.')))
        sum_house[0] =sum_houses[0]
        sum_house[1] = sum_houses[1]
        sum_house[2] = sum_houses[2]
        sum_house[3] = sum_houses[3]
        sum_house[4] = sum_houses[4]
    
        favourates.sort()
        favourate_median.append(int(np.median(favourates)))
        medians.sort()
        median.append(np.median(medians))
        # price = avg_work_year
        b = len(avg_work_year)
        b1= len(favourates)
    
        sum = 0
        sum1 = 0
        for i in avg_work_year:
            sum = sum+float(i)
        avgs.append(round(sum/b, 2))
        for i in favourates:
            sum1 = sum1+float(i)
        favourate_avg.append(round(int(sum1/b1), 2))
    
    for i in places:
        avg(i)
    
    print("各区平均房价", avgs)
    print('各房型的出售总数:', sum_house)
    print("房间面积", area)
    """
    [280, 56, 504, 1676, 1680]
    [392, 112, 448, 1679, 1680]
    [224, 0, 616, 3359, 3360]
    [448, 112, 280, 1679, 1680]
    [504, 0, 336, 1680, 1679]
    [224, 56, 168, 1680, 1670]
    
    
    [66.17, 65.6, 76.04, 78.94, 62.06, 74.37] 
    [68.8, 67.8, 79.8, 70.8, 57.6, 78.8]
    [6, 6, 9, 4, 4, 4] [5, 4, 3, 2, 3, 2]
    """
    # print(median)
    # print(favourate_avg,favourate_median)
    line = Line()
    line.add_xaxis(place)
    line.add_yaxis("贵阳各地房价平均值(万元)", avgs)
    line.add_yaxis("贵阳各地房价中位数值(万元)", median)
    # line.render("predict_line.html")
    
    def bar() -> Bar:
        c = (
            Bar({"theme": ThemeType.MACARONS})
                .add_xaxis(place)
                .add_yaxis("平均值", avgs)
                .add_yaxis("中位数", median)
                .set_global_opts(
                title_opts={"text": "贵阳各地房价(万元)"}
            )
        )
        return c
    bar().render("predict_bar.html")
    # print(sum_house)
    def bar() -> Bar:
        c = (
            Bar({"theme": ThemeType.MACARONS})
                .add_xaxis(houseidfo)
                .add_yaxis(place[0], [280, 56, 504, 1676, 1680])
                .add_yaxis(place[1], [392, 112, 448, 1679, 1680])
                .add_yaxis(place[2], [224, 0, 616, 3359, 3360])
                .add_yaxis(place[3], [448, 112, 280, 1679, 1680])
                .add_yaxis(place[4], [504, 0, 336, 1680, 1679])
                .add_yaxis(place[-1], sum_house)
                # .add_yaxis("中位数", favourate_median)
                .set_global_opts(
                title_opts={"text": "贵阳各地房型\n数量"}
            )
        )
        return c
    # bar().render("house_bar.html")
    line = Line()
    line.add_xaxis(place)
    line.add_yaxis("贵阳各地房子平均面积\n(平米)", area)
    line.render("Area_line.html")
    
    
    
    list_num = favourate_avg
    attr = place
    # print(zip(attr, list_num))
    s = [list(z) for z in zip(attr, list_num)]
    c = (Pie().add("", s).set_global_opts(title_opts=opts.TitleOpts(title="贵阳市各区楼房\n平均收藏人数"))
         .set_series_opts(label_opts=opts.LabelOpts(formatter="{b}: {c}"))
         )
    c.render("pie_avg.html")
    
    list_num = favourate_median
    attr = place
    # print(zip(attr, list_num))
    s = [list(z) for z in zip(attr, list_num)]
    c = (Pie().add("", s).set_global_opts(title_opts=opts.TitleOpts(title="贵阳市各区楼房\n收藏人数中位数"))
         .set_series_opts(label_opts=opts.LabelOpts(formatter="{b}: {c}"))
         )
    c.render("pie_median.html")
    
    from pyecharts import options as  opts
    from pyecharts.charts import Scatter3D
    from pyecharts.faker import Faker
    
    
    price=[float(i)/1 for i in price]
    # print(price)
    # types=list(map(mapfunc,df.house_type.values))
    # type = [224, 56, 168, 1680, 1670]
    data = []
    # print(fav,type)
    # for j in range(len(type)):
    #     for k in range(len(fav)):
    for j in range(100):
        for k in range(100):
            for i in range(500):
                try:
                    data.append([type[j], favourate_avg[k],price[i]])
                except:
                    continue
    # print(data)
    scatter = (
         Scatter3D(init_opts=opts.InitOpts(width='900px', height='600px'))  # 初始化
              .add("", data,
                   grid3d_opts=opts.Grid3DOpts(
                        width=300, depth=300, rotate_speed=300, is_rotate=True,
                   ),)
    
              # 设置全局配置项
              .set_global_opts(
              title_opts=opts.TitleOpts(title="房型——关注度——价格\n三维关系图"),  # 添加标题
              visualmap_opts=opts.VisualMapOpts(
                   max_=100,  # 最大值
                   pos_top=200,  # visualMap 组件离容器上侧的距离
                   range_color=Faker.visual_color  # 颜色映射
              )
         )
              # .render("3D散点图.html")
    )
    print('数据分析和可视化结束,左边点开~')
    

    同时赠送给大家另一个版本的:

    爬虫:链家网:柳州市

    # -*- coding: utf-8 -*-
    import scrapy
    
    
    import requests
    from lxml import etree
    import xlwt
    import xlrd
    import csv
    import pandas as pd
    import time
    
    class LanjiaSpider:
        def __init__(self):
            self.url = 'https://liuzhou.lianjia.com/ershoufang/yufengqu/pg{}/'
            self.headers = {
                "User-Agent": "Mozilla/5.0 (Windows NT 10.0; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/75.0.3770.100 Safari/537.36"}
    
        def get_response_spider(self, url_str):  # 发送请求
            get_response = requests.get(self.url, headers=self.headers)
            time.sleep(2)
            response = get_response.content.decode()
            html = etree.HTML(response)
            return html
        def get_content_html(self, html):  # 使xpath获取数据
            self.houseInfo = html.xpath('//div[@class="houseInfo"]/text()')
            self.title = html.xpath('//div[@class="title"]/a/text()')
            self.positionInfo = html.xpath('//div[@class="positionInfo"]/a/text()')
            self.totalPrice = html.xpath('//div[@class="totalPrice"]/span/text()')
            self.unitPrice = html.xpath('//div[@class="unitPrice"]/span/text()')
            self.followInfo = html.xpath('//div[@class="followInfo"]/text()')
            self.tag = html.xpath('//div[@class="tag"]/span/text()')
            # print(title)
            # return houseInfo,title,positionInfo,totalPrice,unitPrice,followInfo,tag
    
        def xpath_houseInfo(self):
            #print(self.houseInfo)
            #print(type(self.houseInfo))
            # df = pd.DataFrame({"houseInfo": self.houseInfo,"tite":self.title,"positionInfo":self.positionInfo,"totaPrice":self.totalPrice,"unitPrice":self.unitPrice,"followInfo":self.followInfo,"tag":self.tag})
            # df=pd.DataFrame({"houseInfo": self.houseInfo,"tite":self.title})
            # df.to_excel(r'C:\Users\wy\Desktop\sublime\链家\pand3.xlsx')
            # a=len(self.houseInfo)
            for i in range(len(self.houseInfo)):
                # print(i)
                # yield i
                # print(type(self.houseInfo))
                yield self.houseInfo[i]
    
        def qingxi_data_houseInfo(self):  # 清洗数据
    
            self.xpath_houseInfo()
            self.xpath_title()
            self.xpath_positionInfo()
            self.xpath_totalPrice()
            self.xpath_unitPrice()
            self.xpath_followInfo()
            self.xpath_tag()
            get_houseInfo = self.xpath_houseInfo()
            get_title = self.xpath_title()
            get_positionInfo=self.xpath_positionInfo()
            get_totalPrice = self.xpath_totalPrice()
            get_unitPrice = self.xpath_unitPrice()
            get_followInfo=self.xpath_followInfo()
            get_tag=self.xpath_tag()
            i = 1
            while True:
                data_houseInfo= next(get_houseInfo)
                data_title=next(get_title)
                data_positionInfo=next(get_positionInfo)
                data_totalPrice=next(get_totalPrice)
                data_unitPrice=next(get_unitPrice)
                data_followInfo=next(get_followInfo)
                data_tag=next(get_tag)
    
                with open("yufengqu.csv", "a", newline="", encoding="utf-8-sig") as f:
                    fieldnames = ['houseInfo', 'title', 'positionInfo', 'totalPrice/万元', 'unitPrice', 'followInfo', 'tag']
                    writer = csv.DictWriter(f, fieldnames=fieldnames)  # 写入表头
                    writer.writeheader()
                    list_1 = ['houseInfo', 'title', 'positionInfo', 'totalPrice/万元', 'unitPrice', 'followInfo', 'tag']
                    list_2 = [data_houseInfo,data_title,data_positionInfo,data_totalPrice,data_unitPrice,data_followInfo,data_tag]
                    list_3 = dict(zip(list_1, list_2))
                    writer.writerow(list_3)
                    print("写入第"+str(i)+"行数据")
                i += 1
                if i > len(self.houseInfo):
                    break
    
        def xpath_title(self):
            for i in range(len(self.title)):
                yield self.title[i]
    
        def xpath_positionInfo(self):
            for i in range(len(self.positionInfo)):
                yield self.positionInfo[i]
    
        def xpath_totalPrice(self):
            for i in range(len(self.totalPrice)):
                yield self.totalPrice[i]
        def xpath_unitPrice(self):
            for i in range(len(self.unitPrice)):
                yield self.unitPrice[i]
        def xpath_followInfo(self):
            for i in range(len(self.followInfo)):
                yield self.followInfo[i]
        def xpath_tag(self):
            for i in range(len(self.tag)):
                yield self.tag[i]
        def run(self):
            i = 1
            while True:
                url_str = self.url.format(i)  # 构造请求url
                html = self.get_response_spider(url_str)
                self.get_content_html(html)
                self.qingxi_data_houseInfo()
    
                i += 1
                if i == 100:  # 不包括100页
                    break
    
    
    # if __name__ == "__main__":
    #     lanjia = LanjiaSpider()
    #     lanjia.run()
    
    class MyspiderSpider(scrapy.Spider):
        name = 'myspider'
        allowed_domains = ['https://wh.lianjia.com/ershoufang/jianghan/']
        start_urls = ['https://wh.lianjia.com/ershoufang/jianghan//']
    
        def parse(self, response):
            print('爬取ing....')
            lanjia = LanjiaSpider()
            lanjia.run()
    
    
    
    

    数据可视化:(优化版)

    """
    数据分析及可视化
    auuthor: 周小夏
    """
    import pandas as pd
    from pyecharts.charts import Line, Bar
    import numpy as np
    from pyecharts.globals import ThemeType
    from pyecharts.charts import Pie
    from pyecharts import options as opts
    
    
    places = ['chengzhongqu', 'liubeiqu', 'liuchengxian', 'liujiangqu', 'liunanqu', 'yufengqu']
    place = ['城中区', '柳北区', '柳城县', '柳江区', '柳南区', '鱼峰区']
    avgs = []  # 房价均值
    median = []  # 房价中位数
    favourate_avg = []  # 房价收藏人数均值
    favourate_median = []  # 房价收藏人数中位数
    houseidfo = ['2室1厅', '3室1厅', '2室2厅', '3室2厅', '其他']  # 房型定义
    houseidfos = ['2.1', '3.1', '2.2', '3.2']
    sum_house = [0,  0, 0, 0, 0]  # 各房型数量
    sum_houses = []
    price = []  # 房价均值
    unitprice = []  # 单价
    fav = []  # 收藏人数
    type = []
    area = []  # 房间
    
    
    def avg(name):
        df = pd.read_csv('./spiders/' + str(name)+'.csv', encoding='utf-8')
        pattern = '\d+'
        df['totalPrice/万元'] = df['totalPrice/万元'].str.findall(pattern)
        df['followInfo'] = df['followInfo'].str.findall(pattern)
        df['houseInfo'] = df['houseInfo'].str.findall(pattern)
        df['unitPrice'] = df['unitPrice'].str.findall(pattern)
    
        sum_houses = [0, 0, 0, 0, 0]
        # print(sum_house)
        avg_work_year = []
        areas = []
        unit_avg = []
        medians = []
        favourates = []
        k = 0
        k1 = 0
        k3 = 0
        k4 = 0
    
        for i in range(len(df)):
            if (i + 1) % 2 == 0:
                continue
            else:
                if len(df['unitPrice'][i]) >= 0:
                    unit_avg.append(','.join(df['unitPrice'][i]).replace(',', '.'))
                if len(df['totalPrice/万元'][i]) >= 0:
                    avg_work_year.append(','.join(df['totalPrice/万元'][i]).replace(',', '.'))
                    medians.append(float(','.join(df['totalPrice/万元'][i]).replace(',', '.'))*100)
                    price.append(','.join(df['totalPrice/万元'][i]).replace(',', '.'))
                if len(df['followInfo'][i]) ==2:
                    favourates.append(int(','.join(df['followInfo'][i][:1])))
                    fav.append(int(','.join(df['followInfo'][i][:1])))
                if float(','.join(df['houseInfo'][i][:2]).replace(',', '.')) == 2.1:
                    k +=1
                    sum_houses[0] =k
                    type.append(2.1)
                if float(','.join(df['houseInfo'][i][:2]).replace(',', '.')) == 3.1:
                    k1 +=1
                    sum_houses[1] =k1
                    type.append(3.1)
                if float(','.join(df['houseInfo'][i][:2]).replace(',', '.')) == 2.2:
                    k3 +=1
                    sum_houses[2] =k3
                    type.append(2.2)
                if float(','.join(df['houseInfo'][i][:2]).replace(',', '.')) == 3.2:
                    k4 +=1
                    sum_houses[3] =k4
                    type.append(3.2)
                else:
                    k4 +=1
                    sum_houses[4] = k4
                    type.append('other')
                areas.append(float(','.join(df['houseInfo'][i][2:4]).replace(',', '.')))
        sum_house[0] =sum_houses[0]
        sum_house[1] = sum_houses[1]
        sum_house[2] = sum_houses[2]
        sum_house[3] = sum_houses[3]
        sum_house[4] = sum_houses[4]
        sum_house.append(sum_house[0])
        sum_house.append(sum_house[1])
        sum_house.append(sum_house[2])
        sum_house.append(sum_house[3])
        sum_house.append(sum_house[4])
        # print(sum_houses)
        favourates.sort()
        favourate_median.append(int(np.median(favourates)))
        medians.sort()
        median.append(np.median(medians))
        # price = avg_work_year
        b = len(avg_work_year)*100
        b1= len(favourates)
        b2 = len(unit_avg)
        b4 = len(areas)*100
        sum = 0
        sum1 = 0
        for i in unit_avg:
            sum = sum+float(i)
        unitprice.append(round(sum/b2, 2))
        for i in areas:
            sum = sum+float(i)
        area.append(round(sum/b4, 2))
        for i in avg_work_year:
            sum = sum+float(i)
        avgs.append(round(sum/b, 2))
        for i in favourates:
            sum1 = sum1+float(i)
        favourate_avg.append(round(int(sum1/b1), 2))
    
    for i in places:
        avg(i)
    
    print("各区平均房价", avgs)
    print('各房型的出售总数:', sum_house)
    print("房间面积", area)
    print("房价单价", unitprice)
    
    a = []
    for i in median:
        a.append(i/100)
    # print(median)
    # print(favourate_avg,favourate_median)
    line = Line()
    line.add_xaxis(place)
    line.add_yaxis("柳州市各地房价平均值(万元)", avgs)
    line.add_yaxis("柳州市各地房价中位数值(万元)", a)
    line.render("predict_line.html")
    
    def bar() -> Bar:
        c = (
            Bar({"theme": ThemeType.MACARONS})
                .add_xaxis(place)
                .add_yaxis("平均值", unitprice)
                .set_global_opts(
                title_opts={"text": "柳州市各地房价单价(元)"}
            )
        )
        return c
    
    bar().render("unit_prices.html")
    def bar() -> Bar:
        c = (
            Bar({"theme": ThemeType.MACARONS})
                .add_xaxis(place)
                .add_yaxis("平均值", avgs)
                .add_yaxis("中位数", a)
                .set_global_opts(
                title_opts={"text": "柳州市各地房价(万元)"}
            )
        )
        return c
    bar().render("predict_bar.html")
    # print(sum_house)
    def bar() -> Bar:
        c = (
            Bar({"theme": ThemeType.MACARONS})
                .add_xaxis(houseidfo)
                .add_yaxis(place[0], sum_house[0:5])
                .add_yaxis(place[1], sum_house[5:10])
                .add_yaxis(place[2], sum_house[10:15])
                .add_yaxis(place[3], sum_house[15:20])
                .add_yaxis(place[4], sum_house[20:25])
                .add_yaxis(place[-1], sum_house[25:30])
                # .add_yaxis("中位数", favourate_median)
                .set_global_opts(
                title_opts={"text": "柳州市各地房型\n数量"}
            )
        )
        return c
    bar().render("house_bar.html")
    
    line = Line()
    line.add_xaxis(place)
    line.add_yaxis("柳州市各地房子平均面积\n(平米)", area)
    line.render("Area_line.html")
    
    
    
    list_num = favourate_avg
    attr = place
    # print(zip(attr, list_num))
    s = [list(z) for z in zip(attr, list_num)]
    c = (Pie().add("", s).set_global_opts(title_opts=opts.TitleOpts(title="柳州市各区楼房\n平均收藏人数"))
         .set_series_opts(label_opts=opts.LabelOpts(formatter="{b}: {c}"))
         )
    c.render("pie_avg.html")
    
    list_num = favourate_median
    attr = place
    # print(zip(attr, list_num))
    s = [list(z) for z in zip(attr, list_num)]
    c = (Pie().add("", s).set_global_opts(title_opts=opts.TitleOpts(title="柳州市各区楼房\n收藏人数中位数"))
         .set_series_opts(label_opts=opts.LabelOpts(formatter="{b}: {c}"))
         )
    c.render("pie_median.html")
    
    from pyecharts import options as  opts
    from pyecharts.charts import Scatter3D
    from pyecharts.faker import Faker
    
    
    line = Line()
    line.add_xaxis(place)
    line.add_yaxis("房间面积\n(平米)", area)
    line.add_yaxis("房价\n(/万元)", avgs)
    line.render("price1_line.html")
    
    
    price=[float(i)/1 for i in price]
    # print(price)
    # types=list(map(mapfunc,df.house_type.values))
    # type = [224, 56, 168, 1680, 1670]
    data = []
    # print(fav,type)
    # for j in range(len(type)):
    #     for k in range(len(fav)):
    for j in range(100):
        for k in range(100):
            for i in range(500):
                try:
                    data.append([type[j], favourate_avg[k],price[i]])
                except:
                    continue
    # print(data)
    scatter = (
         Scatter3D(init_opts=opts.InitOpts(width='900px', height='600px'))  # 初始化
              .add("", data,
                   grid3d_opts=opts.Grid3DOpts(
                        width=300, depth=300, rotate_speed=300, is_rotate=True,
                   ),)
    
              # 设置全局配置项
              .set_global_opts(
              title_opts=opts.TitleOpts(title="房型——关注度——价格\n三维关系图"),  # 添加标题
              visualmap_opts=opts.VisualMapOpts(
                   max_=300,  # 最大值
                   pos_top=200,  # visualMap 组件离容器上侧的距离
                   range_color=Faker.visual_color  # 颜色映射
              )
         )
              .render("3D散点图.html")
    )
    print('数据分析和可视化结束,左边点开~')
    

    最后,别忘记了关注公众号~

    分享最新算法!

    [外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-TYq1lpiO-1594978846618)(D:\CSDN\pic\WeChat Image_20200716151357.jpg)]

    展开全文
  • Python数据清洗实战入门

    万人学习 2019-12-09 10:47:41
    本次课程主要以真实的电商数据为基础,通过Python详细的介绍了数据分析中的数据清洗阶段各种技巧和方法。
  • 数据清洗 Chapter01 | 数据清洗概况

    千次阅读 多人点赞 2020-04-17 09:33:43
    不登高山,不知天之高也;不临深溪,不知地之厚也。...Chapter01 | 数据清洗概况一、什么是数据1、数据的类型2、表格数据3、属性类别二、数据清洗1、什么是数据清洗2、为什么要进行数据清洗3、数据存在的问题三、数据...

    这篇文章讲述的是数据存储方式和数据类型等基本概念、数据清洗的必要性和质量评价的关键点。希望这篇数据清洗的文章对您有所帮助!如果您有想学习的知识或建议,可以给作者留言~


    一、什么是数据

    从广泛的意义上来讲,数据是一个宽泛的概念

    • 计算机中的0101代码
    • 日常生活中的音乐,图片,视频等
    • 人类的语言、文字
    • 了解数据清洗,需要理解数据的内涵和外延

    1、数据的类型

    • 1、表格数据

    关系记录、数据矩阵、向量、事务数据
    1

    • 2、图和网络

    万维网、社交网络、分子结构
    2

    • 3、多媒体数据

    文本、图像、视频、音频
    3

    2、表格数据

    在此,只了解表格数据

    • 1、数据集(数据库)

    • 由数据对象构成

    • 一个数据对象表示一个实体

    • 2、概念

    下面的这些表示相似的概念,在不同的地方可以交叉使用

    • 样本(samples or examples)
    • 对象(objects)
    • 实例(instances)
    • 元组(tuples)
    • 数据点(data points)

    数据对象由属性(attributes)及其值(value)构成

    表格数据中的行为数据对象,列为特征。如下图:
    4

    3、属性类别

    类型:

    • 名义型(Nominal)

    • 布尔型(Binary)

    • 等级型(Ordinal)

    • 数值型(Numeric)

    • 3.1、名义型
      对数据对象进行分类或分组,使同类同质,异类异质

    eg:
    汽车品牌 ={路虎,奥迪,大众,奥拓}
    学校 = {北大,清华,武大}

    其值只是不同类别的代码,不能区分大小写,更不能进行任何数学计算

    • 3.2、布尔型
      布尔型数据是在条件或循环中的条件判断

    Python中布尔类型对应两个布尔值:True和False,分别对应1和0
    5

    • 3.3、等级型
      将数据对象分成不同的类型
      确定所分类别的等级差别和序列差别

    eg:
    身高:高、中、低
    年级:三年级、二年级
    6

    等级行只能比较大小,不能进行数学计算

    • 3.4、数值型
      最常见的数据类型
      直接使用自然数或可进行测量的具体数值

    可直接用数值计算方法进行汇总和分析
    7

    二、数据清洗

    1、什么是数据清洗

    脏数据
    8

    • 数据清洗
      从一个充满拼写错误,缺失值,异常值等问题的原始数据集(Raw Data)通过数据转换,缺失处理,异常处理等手段映射为一个符合质量要求的“新”数据集(Consistent Data)的过程
      9

    数据清洗在大数据分析流程中的位置
    10

    2、为什么要进行数据清洗

    • 从不同渠道获得的数据,集成在一起,组成新的数据集,需要进行数据清洗,来保证数据集的质量
    • 数据分析算法对输入的数据集有要求
    • 显示情况下的数据集质量不禁如人意,需要数据清洗

    3、数据存在的问题

    • 1、单数据源
    1. 违背属性约束条件:日期,电话号码,身份证号等
    2. 属性违反唯一性:主键同一取值出现多次
    3. 数据更新不及时
    4. 数据存在噪音
    5. 数据存在拼写错误
    6. 数据存在相似,重复记录
    • 2、多数据源
    1. 同一属性存在不同的名称:人的真实姓名和绰号
    2. 同一属性存在不同的定义:字段的长度测量单位,类型不一致
    3. 数据存在重复,拼写错误
    4. 数据的汇总时间不一致:按照年度,季度,月度统计
    5. 数据的存储单位不一致:按照GB,TB为单位存储

    三、数据质量评估

    如何评估数据的质量?
    准确性,一致性,时效性,完整性,数据重复,数据冗余
    易用性和可维护性
    相关性和可信度

    • 1、准确性

    考察数据集记录的信息是否存在异常或错误
    业务数据通常存在特征取值缺失,特征缺失,主键缺失等问题
    问题多发生在数据的源头,由各种主客观原因(主观录入错误,数据需求不明确,数据提供者故意隐瞒等)所导致
    要获得高质量的数据集,需要把控好数据收集,数据录入的源头

    • 2、一致性

    考察数据是否符合统一规范,数据记录是否保持统一格式

    数据一致性问题通常存在于数据整合阶段:

    来自不同数据源的数据汇总在一起,特征的表述不相同
    相同的特征名称在不同的数据源中代表不同的含义

    • 1、特征名称不同,含义相同

    通过其相应的取值范围和与其他特征的相似性,来找出这些指标对特征名称进行统一

    在医疗指标数据中,有reference字段,代表指标值的正常值范围
    如:身高的reference会是150-180,体重会是50-80
    通过reference来初步判断哪些指标代表的含义相同

    • 2、特征名称相同,含义不同

    不同医疗器械采集的数据中通常含有名称为蛋白的字段,但特征可能指尿蛋白,也可能指血蛋白
    在实际操作中需要组合成新的特征(尿蛋白,血蛋白)

    • 3、时效性

    考察数据从产生到分析的时间间隔,也称为数据的延长时长
    数据集所代表的信息并不一定能正确描述当前的情形
    爬取动态网页内容
    由于网页内容,结构都在变化,获取的数据带有明显的时效性
    考虑到数据获取的时间成本
    数据分析的周期不能过长,否则会导致分析的结论失去现实意义

    • 4、完整性

    考察数据信息是否存在缺失,包括数据集的字段以及数据记录

    • 5、数据重复

    考察数据特征,数据记录的重复情况

    • 6、易用性和可维护性

    考察数据的使用与访问情况,以及数据的更新,维护状况

    • 7、相关性和可信度

    考察数据与相关业务的相关情况,参考数据的实用性

    • 8、数据冗余

    考察数据集特征之间的相关性
    如果一个特征可由另一个特征推导出来,那么这两个特征存在冗余
    年龄可由生日推算获得,那么年龄和生日之间存在冗余
    计算两个特征之间的相关系数来测量二者的冗余程度

    计算两个特征之间的相关系数可以来测量二者之间的冗余程度

    • 1、连续型数据相关性检验:

    Pearson相关系数用于计算连续型变量之间的相关性
    公式:
    11
    其中,ρA,ρB分别为变量A和B的标准差
    相关系数r的取值范围为[-1,1]
    r>0,特征A和特征B呈正相关关系
    r=0,特征A和特征B独立,不存在相关性
    r<0,特征A和特征B呈负相关关系
    |r|值越大,两个特征之间的相关性越高

    • 2、离散型数据相关性检测:

    卡方独立性检验用于离散型数据的相关性检测 ,也成为列联表(contingency table),卡方检验

    卡方独立性检验的步骤:

    零假设:变量A和变量B无关
    水平:确定显著水平α
    检验:依据零假设,计算卡方值
    确定自由度,根据自由度查临界值表进行推断

    eg:
    12
    卡方值和自由度计算
    13
    计算公式:
    14
    自由度计算公式:
    15

    四、数据清洗的主要内容

    16

    • 1、数据初步处理

    使用Python的标准库或者第三方库读入数据,或者将数据读入数据库
    使用数据可视化手段观察数据的取值分布情况
    对数据进行整合或分组

    • 2、缺失值处理

    确定缺失值的范围,以及所站比例
    取出不需要的特征
    使用缺失值填补等方法对缺失值进行填充

    • 3、异常值处理

    检测异常值:基于统计,举例,密度的检测方法,复杂方法如孤立森林
    处理检测值:删除异常值
    保留异常值:选择鲁棒性更强的学习算法

    • 4、数据转换

    数据的格式进行统一:不同数据文件格式的转换
    数据去重:取出重复的数据几率,提高算法进行效率
    数据标准化:消除数据单位,量纲不同带来的影响
    数据离散化:将连续型数据转换为离散型数据,增强模型对于异常值的鲁棒性


    各位路过的朋友,如果觉得可以学到些什么的话,点个赞再走吧,欢迎各位路过的大佬评论,指正错误,也欢迎有问题的小伙伴评论留言,私信。每个小伙伴的关注都是本人更新博客的动力!!!

    展开全文
  • 数据分析学习笔记-----数据清洗数据清洗概述 数据概述 从广泛的意义上来讲,数据是一个宽泛的概念,包括但不限于: 计算机中的0101代码 日常生活中的音乐,图片,视频 人类的语言,文字 … 我们要了解数据清洗,...

    数据分析学习笔记-----数据清洗之数据清洗概述

    数据概述

    从广泛的意义上来讲,数据是一个宽泛的概念,包括但不限于:

    • 计算机中的0101代码
    • 日常生活中的音乐,图片,视频
    • 人类的语言,文字

    我们要了解数据清洗,就需理解数据的内涵和外延

    常见的数据有:

    • 表格数据:关系记录、数据矩阵、向量、事务数据
    • 图和网络:万维网、社交网络、分子结构
    • 多媒体数据:文本 、图像、视频、音频

    其中,比较重要比较常见的分析数据是表格数据。这里重点介绍一些关于表格数据的内容。

    表格数据

    • 数据集(数据库)
      由数据对象构成,一个数据对象表示一个实体

    • 概念

      • 样本(samples or examples)
      • 实例(instances)
      • 数据点(data points)
      • 对象(objects)
      • 元组(tuples)
    • 数据对象由属性(attributes)及其值(value)构成

      • 表格数据行为数据对象
      • 表格数据列为特征
    • 表格数据的特征

      • 类型
        名义型(Nominal)
        布尔型(Binary)
        等级型(Ordinal)
        数值型(Numeric)

    数据清洗的重要性

    什么是数据清洗 ?数据清洗是从一个充满拼写错误,缺失值,异常值等问题的原始数据集(Raw Data)通过数据转换,缺失处理,异常处理等手段映射为一个符合质量要求的“新”数据集(Consistent Data)的过程。

    数据清洗在大数据分析流程中的位置:

    • 数据采集
    • 数据解析
    • 数据清洗
    • 数据分析
    • 数据应用

    为什么要数据清洗?

    • 从不同渠道获得的数据,集成在一起,组成新的数据集,需要进行数据清洗,来保证数据集的质量
    • 数据分析算法对输入的数据集有要求
    • 现实情况下的数据集质量不尽如人意,需要数据清洗

    数据存在的问题:

    • 单数据源

      • 违背属性约束条件:日期,电话号码,身份证号等
      • 属性违反唯一性:主键同一取值出现多次
      • 数据更新不及时
      • 数据存在噪音
      • 数据存在拼写错误
      • 数据存在相似,重复记录
    • 多数据源

      • 同一属性存在不同的名称:人的真实姓名和绰号
      • 同一属性存在不同的定义:字段的长度测量单位,类型不一致
      • 数据存在重复,拼写错误
      • 数据的汇总时间不一致:按照年度,季度,月度统计
      • 数据的存储单位不一致:按照GB,TB为单位存储

    数据质量评估

    如何评估数据的质量?
    常用的评价数据质量的指标有以下几种:

    • 准确性,一致性,时效性,完整性,数据重复,数据冗余
    • 易用性和可维护性
    • 相关性和可信度

    准确性:考察数据集记录的信息是否存在异常或错误

    • 业务数据通常存在特征取值缺失,特征缺失,主键缺失等问题
    • 问题多发生在数据的源头,由各种主客观原因(主观录入错误,数据需求不 明确,数据提供者故意隐瞒等)所导致
    • 要获得高质量的数据集,需要把控好数据收集,数据录入的源头

    一致性 :考察数据是否符合统一规范,数据记录是否保持统一格式
    数据一致性问题通常存在于数据整合阶段:

    • 来自不同数据源的数据汇总在一起,特征的表述不相同
    • 相同的特征名称在不同的数据源中代表不同的含义
      • 特征名称不同,含义相同
      • 特征名称相同,含义不同

    时效性:考察数据从产生到分析的时间间隔,也称为数据的延时时长

    • 数据集所代表的信息并不一定能正确描述当前的情形
    • 爬取动态网页数据,由于网页内容,结构都在变化,获取的数据带有明显的时效性
    • 考虑到数据获取的时间成本,数据分析的周期不能过长,会导致分析的结论失去现实意义

    完整性:考察数据信息是否存在缺失,包括数据集的字段以及数据记录

    数据重复:考察数据特征,数据记录的重复情况

    易用性和可维护性:考察数据的使用和访问情况,以及数据的更新,维护状况

    相关性和可信度:考察数据与实际业务的相关情况,考察数据的实用性

    数据冗余:考察数据集特征之间的相关性
    如果一个特征能由另外的特征推导出来,那么该特征可能是冗余的。比如,年龄可以由生日推算获得,那么年龄和生日之间存在冗余。使用定量的相关分析考察特征之间的冗余程度

    • 离散型特征之间的冗余程度:卡方检验
    • 连续型特征之间的冗余程度:相关系数

    数据清洗的主要内容

    数据初步处理

    • 使用Python的标准库或者第三方库读入数据,或者将数据读入数据库
    • 使用数据可视化手段观察数据的取值分布情况
    • 对数据进行整合或分组

    缺失值处理

    • 确定缺失值的范围,以及所占比例
    • 去除不需要的特征
    • 使用缺失值填补等方法对缺失值进行填

    异常值处理

    • 检测异常值:基于统计,距离,密度的检测方法,复杂方法如孤立森林
    • 处理异常值:删除异常值
    • 保留异常值:选择鲁棒性更强的学习算法

    数据转换

    • 数据的格式进行统一:不同数据文件格式的转换
    • 数据去重:去除重复的数据记录,提高算法运行效率
    • 数据标准化:消除数据单位,量纲不同带来的影响
    • 数据离散化:将连续型数据转换为离散型数据,增强模型对于异常值的鲁棒性
    展开全文
  • 数据清洗技术——Excel数据清洗一、实验目的和要求二、实验环境三、实验内容和实验步骤 一、实验目的和要求 1、了解 Excel 的基本功能和用途 2、掌握 Excel 数据清洗的基本步骤 3、了解 Excel 数据清洗的方法 4、...
  • Hadoop_数据清洗示例

    万次阅读 2020-05-12 16:56:14
    Hadoop_数据清洗 示例(去除空行、开头为空格的数据): 原始数据:D:\data\testdata.txt zhangsan 500 450 jan zhangsan 550 450 feb lisi 210 150 jan lisi 200 150 feb zhangsan 400 150 march zhangsan 600...
  • kettle数据清洗

    2018-09-18 16:48:30
    利用kettle工具进行数据清洗,按照条件去除不需要的内容
  • RFID数据清洗和一般数据清洗的不同: RFID数据清洗已经跨越到硬件范畴!造成脏数据的原因是硬件原理和硬件所处环境本身!要提高RFID数据清洗能力,就必须同时研究技术原理和环境本身之间的互动关系,而这已经超出了...
  • 没有合格的食材,再好的厨师也做不出绝世佳肴;没有合格的钢材,再好的建筑...数据的“脏”在于数据有重复、数据有缺失、数据有不一致,数据清洗的目的就是为了删除重复数据、补齐缺失的数据、消除数据的不一致,保...
  • 数据清洗是整个数据分析过程的第一步,就像做一道菜之前需要先择菜洗菜一样。 数据分析师经常需要花费大量的时间来清洗数据或者转换格式,这个工作甚至会占整个数据分析流程的80%左右的时间。 在这篇文章中,我...

空空如也

空空如也

1 2 3 4 5 ... 20
收藏数 22,486
精华内容 8,994
关键字:

数据清洗