首页 > 其他分享 >数据采集——数据清洗

数据采集——数据清洗

时间:2023-04-12 21:31:48浏览次数:42  
标签:item import content 采集 gram output input 清洗 数据

数据清洗

到目前为止,我们还没有处理过那些样式不规范的数据,要么是使用样式规范的数据源, 要么就是彻底放弃样式不符合我们预期的数据。但是在网络数据采集中,你通常无法对采 集的数据样式太挑剔。

由于错误的标点符号、大小写字母不一致、断行和拼写错误等问题,零乱的数据(dirty data)是网络中的大问题。本章将介绍一些工具和技术,通过改变代码的编写方式,帮你 从源头控制数据零乱的问题,并且对已经进入数据库的数据进行清洗。

编写代码清洗数据

和写代码处理异常一样,你也应该学习编写预防型代码来处理意外情况。

在语言学里有一个模型叫 n-gram,表示文字或语言中的 n 个连续的单词组成的序列。在进 行自然语言分析时,使用 n-gram 或者寻找常用词组,可以很容易地把一句话分解成若干个 文字片段。

这一节我们将重点介绍如何获取格式合理的 n-gram,并不用它们做任何分析。


from urllib.request import urlopen
from bs4 import BeautifulSoup

def getNgrams(input, n):
  input = input.split(' ')
  output = []
  for i in range(len(input)-n+1):
    output.append(input[i:i+n])
  return output

html = urlopen("https://baike.baidu.com/item/Python/407313")
bsObj = BeautifulSoup(html, "html.parser")
content = bsObj.find("div", {"class":"para"}).get_text()
ngrams = getNgrams(content, 2)
print(ngrams)
print("2-grams count is: "+str(len(ngrams)))


ngrams 函数把一个待处理的字符串分成单词序列(假设所有单词按照空格分开),然后增 加到 n-gram 模型(本例中是 2-gram)里形成以每个单词开始的二元数组。


 ['官方文档(英文)\xa0\n.Python3', '官方文档[引用日期2015-01-14]\n10.\n\xa0\xa0\n网络课程'], ['官方文档[引用日期2015-01-14]\n10.\n\xa0\xa0\n网络课程', 'python'], ['python', '网络教育-百度传课\xa0\n.百度传课[引用日期2016-09-24]\n\n\n']]
 

不过,同时也会出现一些零乱的数据:


\n#!/usr/bin/python\r\nimport\xa0os\r\nprint"Content-type:text/html\\r\\n\\r\\n"\r\nprint"Environment"\r\nfor\xa0param\xa0in\xa0os.environ.keys():\r\n\xa0\xa0\xa0\xa0print"<b>%20s</b>:%s<\\br>"\xa0%(param,os.environ[param])\n\n\n\n\nPython特点\n编辑\n\n\n\n\n\n\n\nPython优点\n\n简单:Python是一种代表简单主义思想的语言。阅读一个良好的Python程序就感觉像是在读英语一样。它使你能够专注于解决问题而不是去搞明白语言本身。\n易学:Python极其容易上手,因为Python有极其简单的说明文档[6]\xa0\n。\n速度快:Python'], ['服务器的主机名、别名或IP地址。\nSERVER_SOFTWARE\n这个环境变量的值包含了调用CGI程序的HTTP服务器的名称和版本号。例如,上面的值为Apache/2.2.14(Unix)\n以下是一个简单的CGI脚本输出


让我们首先用一些正则表达式来移除转义字符( \n ),再把 Unicode 字符过滤掉。我们可以 通过下面的函数对之前输出的结果进行清理:

这里首先把内容中的换行符(或者多个换行符)替换成空格,然后把连续的多个空格替换 成一个空格,确保所有单词之间只有一个空格。最后,把内容转换成 UTF-8 格式以消除转 义字符。


def ngrams(input, n):
    content = re.sub('\n+', " ", content)
    content = re.sub(' +', " ", content)
    content = bytes(content, "UTF-8")
    content = content.decode("ascii", "ignore")
    print(content)
    input = input.split(' ')
    output = []
    for i in range(len(input)-n+1):
         output.append(input[i:i+n])
    return output

  • 剔除单字符的“单词”,除非这个字符是“i”或“a”;
  • 剔除维基百科的引用标记(方括号包裹的数字,如 [1]);
  • 剔除标点符号(注意:这个规则有点儿矫枉过正,在第 9 章我们将详细介绍,本例暂时 这样处理)。

from urllib.request import urlopen
from bs4 import BeautifulSoup
import re
import string

def cleanInput(input):
    input = re.sub('\n+', " ", input)
    input = re.sub('\[[0-9]*\]', "", input)
    input = re.sub(' +', " ", input)
    input = bytes(input, "UTF-8")
    input = input.decode("ascii", "ignore")
    cleanInput = []
    input = input.split(' ')
    for item in input:
        item = item.strip(string.punctuation)
        if len(item) > 1 or (item.lower() == 'a' or item.lower() == 'i'):
    cleanInput.append(item)
    return cleanInput
def ngrams(input, n):
    input = cleanInput(input)
    output = []
    for i in range(len(input)-n+1):
          output.append(input[i:i+n])
    return output



from urllib.request import urlopen
from bs4 import BeautifulSoup
import re
import string
from collections import OrderedDict

def cleanInput(input):
    input = re.sub('\n+', " ", input)
    input = re.sub('\[[0-9]*\]', "", input)
    input = re.sub(' +', " ", input)
    input = bytes(input, "UTF-8")
    input = input.decode("ascii", "ignore")
    cleanInput = []
    input = input.split(' ')
    for item in input:
        item = item.strip(string.punctuation)
        if len(item) > 1 or (item.lower() == 'a' or item.lower() == 'i'):
            cleanInput.append(item)
    return cleanInput

def getNgrams(input, n):
    input = cleanInput(input)
    output = dict()
    for i in range(len(input)-n+1):
        newNGram = " ".join(input[i:i+n])
        if newNGram in output:
            output[newNGram] += 1
        else:
            output[newNGram] = 1
    return output

html = urlopen("https://baike.baidu.com/item/Python/407313")
bsObj = BeautifulSoup(html, "html.parser")
content = bsObj.find("div", {"class":"main-content"}).get_text()
ngrams = getNgrams(content, 2)
ngrams = OrderedDict(sorted(ngrams.items(), key=lambda t: t[1], reverse=True))
print(ngrams)


这里用 import string 和 string.punctuation 来获取 Python 所有的标点符号。你可以在 Python 命令行看看标点符号有哪些:



>>> import string
>>> print(string.punctuation)
!"#$%&'()*+,-./:;<=>?@[\]^_`{|}~

在循环体中用 item.strip(string.punctuation) 对内容中的所有单词进行清洗,单词两端 的任何标点符号都会被去掉,但带连字符的单词(连字符在单词内部)仍然会保留。

数据标准化

每个人都会遇到一些样式设计不够人性化的网页,比如“请输入你的电话号码。号码格式 必须是 xxx-xxx-xxxx”。

作为一名优秀的程序员,你可能会问:“为什么不自动地对输入的信息进行清洗,去掉非 数字内容,然后自动把数据加上分隔符呢?”数据标准化过程要确保清洗后的数据在语言 学或逻辑上是等价的,比如电话号码虽然显示成“(555) 123-4567”和“555.123.4567”两 种形式,但是实际号码是一样的。

还用之前的 n-gram 示例,让我们在上面增加一些数据标准化特征。

这段代码有一个明显的问题,就是输出结果中包含太多重复的 2-gram 序列。程序把每个 2-gram 序列都加入了列表,没有统计过序列的频率。掌握 2-gram 序列的频率,而不只是 知道某个序列是否存在,这不仅很有意思,而且有助于对比不同的数据清洗和数据标准化 算法的效果。如果数据标准化成功了,那么唯一的 n-gram 序列数量就会减少,而 n-gram 序列的总数(任何一个 n-gram 序列和与之重复的序列被看成一个 n-gram 序列)不变。也 就是说,同样数量的 n-gram 序列,经过去重之后“容量”(bucket)会减少。

数据存储后再清洗

对于编写代码清洗数据,你能做或想做的事情只有这些。除此之外,你可能还需要处理一 些别人创建的数据库,或者要对一个之前没接触过的数据库进行清洗。 很多程序员遇到这种情况的自然反应就是“写个脚本”,当然这也是一个很好的解决方法。

但是,还有一些第三方工具,像 OpenRefine,不仅可以快速简单地清理数据,还可以让非 编程人员轻松地看见和使用你的数据。

  1. 安装

OpenRefine 的独特之处在于虽然它的界面是一个浏览器,但实际上是一个桌面应用,必 须下载并安装。你可以从它的下载页面(http://openrefine.org/download.html)下载对应 Linux、Windows 和 Mac OS X 系统的版本。

  1. 使用OpenRefine

在下面的例子中,我们将使用维基百科的“文本编辑器对比”表格(https://en.wikipedia. org/wiki/Comparison_of_text_editors)里的内容,如图 7-1 所示。虽然这个表的样式比较规 范,但里面包含了多次编辑的痕迹,所以还是有一些样式不一致的地方。另外,因为这个 数据是写给人看的,而不是让机器看的,所以原来使用的一些样式(比如用“Free”而不 是“$0.00”)不太合适作为 OpenRefine 程序的输入数据。

标签:item,import,content,采集,gram,output,input,清洗,数据
From: https://blog.51cto.com/hiszm/6186272

相关文章

  • 4月12日数据结构,线索二叉树,哈夫曼树,哈夫曼编码
    线索二叉树与以往的二叉树略有不同,普通二叉树在访问到叶子结点的时候会返回,往往递归的效率并不高,有时还可能有栈溢出的风险,但是线索二叉树在访问到叶子结点的时候因为没有左右孩子,所以他左边存放他前驱的指针。右边存放后继的指针,是指从一个非线性结构变成了一个可以线性访问的的......
  • 003.方差&回归分析以及pandas数据分析流程
    一、方差分析   二、回归分析 三、案例讲解 ......
  • 博途基本数据类型总结分析
     ......
  • Android sqlite 数据库查询,插入,删除,更新demo<第1章>
    //20140424创建数据库帮助类DataBaseHelper,继承SQLiteOpenHelper, 1. 编写构造函数,实现数据库创建;publicstaticfinalStringTAG="ListViewActivity";privatestaticintVERSION=1;privatestaticfinalStringTABLE_NAME="user1";privatestaticfinalSt......
  • 数据插入
    09:07:36.078[DEBUG][main][java.sql.Connection]-{conn-100045}PreparingStatement:insertintoRS_ACTIONRECORD(ACTIONNAME,SYSTRNID,OLDSTATUS,NEWSTATUS,AUDITTIMESTAMP,WORKER)values(?,?,?,?,?,?)09:07:36.078[DEBUG][main][java.sql.PreparedS......
  • CentOS系统使用docker-compose安装Doris数据库
    doris当前最新版本为1.2.31、docker与docker-compose安装    docker安装:CentOS安装Docker   docker-compose安装:docker-compose安装与使用2、doris相关下载   1)doris-be、doris-fe2) 3、修改vi/etc/security/limits.conf添加如下信息:*softnofile65......
  • python(十一):小型数据库:shelve
     Python中shelve模块是对象持久化保存方法,将对象保存到文件里面,缺省(即默认)的数据存储文件是二进制的,可以作为一个简单的数据存储方案。使用时,只需要使用open函数获取一个shelf对象,然后对数据进行增删改查操作,在完成工作、并且将内存存储到磁盘中,最后调用close函数变回将......
  • 第三章数据链路层
    3.数据链路层3.1数据链路层概述3.1.1数据链路层的地位我们在学习数据链路层时,可以将其传输单独看作一条传输线路来进行学习3.1.2链路、数据链路、帧链路:是指一个节点到另一个节点之间直接相互连接(有线或者无线),例如主机H1和路由器R1之间相互连接就是一条链路若中......
  • echat 折线图,展示全部数据
    父:importlineChartfrom'./components/accountlintChart.vue'components:{lineChart},要设置 hazardBox的宽高<divclass="hazardBox"><lineChart:chartData="tagTrendData"/></div> 子:......
  • 模型+数据=新模型
    链家BELLEhttps://mp.weixin.qq.com/s/73EI7cY10ERQ075v2Uvyqg,中文对话大模型BELLE全面开源!https://github.com/LianjiaTech/BELLE该项目目前已经开源了如下内容,并且在持续更新中:150万中文指令微调数据集以Bloomz-7b1-mt(70亿参数)为基础,分别在20万,60万,100万,200万数据上进行......