内容采集( 的去重函数-drop_duplicates()函数)
优采云 发布时间: 2022-03-08 14:24内容采集(
的去重函数-drop_duplicates()函数)
数据采集和数据清洗
一、数据清洗1.数据去重(一)相关知识1> pandas读取csv文件-read_csv()2> pandas的去重函数-drop_duplicates()
(二)本关任务(三)参考代码
2.处理空值(一)相关知识1> DataFrame中空值的表示2> 查找空值及计算空值的个数3> 处理空值-fillna
(二)本关任务(三)参考代码
二、数据采集实战1. 单网页爬取(一)相关知识1> 爬虫简介2> 网络爬虫3> 网络爬虫:载入4> 网络爬虫:动态载入5> 网络爬虫:解析
(二)本关任务(三)参考代码
2.网页爬取策略(一)相关知识1> 深度优先爬虫(一路到底)2> 广度优先爬虫(逐层爬取)
(二)本关任务(三)参考代码
3.爬取与反爬取(一)相关知识1>常见反爬手段:2> 应对措施:
(二)本关任务(三)参考代码
4.爬取与反爬取进阶(一)相关知识(二)本关任务(三)参考代码
<a id="_1"></a>一、数据清洗
<a id="1_2"></a>1.数据去重
<a id="_3"></a>(一)相关知识
<a id="1_pandascsvread_csv_4"></a>1> pandas读取csv文件-read_csv()
<p> CSV为简单的文本格式文件,每行为一条用逗号分隔的数据。Excel保存文件时可以选择csv格式;在记事本里输入内容,保存时使用.csv扩展名,也能生成CSV文件。<br /> 只要能阅读文本文件的编辑器,就能打开CSV文件,也可以用Excel把它作为电子表格打开。现在,我们要用pandas中的read_csv函数读取csv文件中的数据。这个函数有很多参数,在本关卡和接下来的关卡中,我们将逐个介绍其中几个常用的参数。<br /> 在本关卡中,我们只需要将CSV文件的文件名作为参数即可。
import pandas as pd
a=pd.read_csv('示例数据.csv')
#此时,a就存储了示例数据.csv文件中的数据
print(a)
# 输出结果如下:
# 1 2
# 0 3 4
# 1 5 6
# 2 1 3
# 3 1 2
# 4 4 2
</p>
2> Pandas的去重功能——drop_duplicates()
pandas 中的 drop_duplicates() 函数是针对 DataFrame 格式的数据,可以去除特定列的重复行。
drop_duplicates() 具有以下参数:
子集=
用于指定需要去重的列。默认为所有列。
保持:{'first', 'last', False}。默认“第一”
删除重复项时是否保留第一次/最后一次出现的项目。当keep=False时,不保留重复;默认情况下保留第一次出现的项目。
就地:布尔值,默认为 False
是否保留修改数据的副本。默认情况下不保留任何副本。
示例代码 1
result_1=a.drop_duplicates()
# 删除a中a、b列均重复的数据;保留第一次出现的重复数据;保留副本
print(result_1)
# 输出结果如下:
# a b
# 0 3 4
# 1 5 6
# 2 3 1
# 3 1 2
# 4 4 2
示例代码 2
result_2=a.drop_duplicates(subset='b', inplace=True)
# 删除a中b列重复的数据;保留第一次出现的重复数据;不保留副本
print(result_2)
# 输出结果为None.因为直接在a上修改,不再将修改结果传递给result_2
print(a)
# 输出结果如下:
# a b
# 0 3 4
# 1 5 6
# 2 3 1
# 3 1 2
(二)本关任务
使用 pandas 将 'basketball.csv' 中的数据导入名为 dataset 的 DataFrame 对象中,并使用 drop_duplicates() 函数对数据集中的 Date 列进行重复数据删除而不保留重复项。返回处理的去重结果和数据集。
(三)参考代码
import pandas as pd
def duplicate():
'''
返回值:
dealed: 对dataset的Date列进行去重后的DataFrame类型数据,不保留副本
dataset: 初始读入的basketball.csv的数据
'''
# 请在此添加代码 完成本关任务
# ********** Begin *********#
dataset = pd.read_csv('basketball.csv')
dealed = dataset.drop_duplicates(subset='Date')
# ********** End **********#
# 返回dealed,dataset
return dealed, dataset
2.处理空值 (一)相关知识1>DataFrame中空值的表示
Pandas 通常将空值表示为 NaN。比如上一关的basketball.csv在OT中有很多空值?字段和备注字段。我们可以取出OT吗?数据前五行的字段,看DataFrame中空值的表示。
import pandas as pd
dataset=pd.read_csv('basketball.csv')
print(dataset["OT?"].ix[:5])
# 输出结果为:
0 NaN
1 NaN
2 NaN
3 NaN
4 NaN
5 NaN
Name: OT?, dtype: object
在数据挖掘过程中,模型通常不能直接接收到 NaN 数据。这需要我们处理空值。在处理空值之前,需要找出空值的个数和位置。
2>查找空值并统计空值个数
Pandas中查找数据表中空值的函数有两个,一个是函数isnull,如果是空值则显示True。另一个函数 notnull 则相反,如果它是空值则显示 False。
用这两个函数求OT数?分别在篮球.csv 数据中的字段和注释字段。下面的程序是一个使用 isnull 函数的例子。
print(dataset[:5].isnull())
# 输出结果为:
Date Score Type Visitor Team VisitorPts Home Team HomePts OT? Notes
0 False False False False False False True True
1 False False False False False False True True
2 False False False False False False True True
3 False False False False False False True True
4 False False False False False False True True
从输出结果看,只有OT?和Notes字段值前五行数据为空,其他非空。notnull函数的用法是一样的,只是输出与isnull函数相反。
接下来我们可能还需要统计数据中空值的数量。为了解决这个问题,我们可以使用 value_counts 函数。该函数的使用示例如下所示:
result=dataset['OT?'].isnull()
#将dataset的OT?字段的空值与否情况传给result
print(result.value_counts())
# 输出结果为:
True 1151
False 79
Name: OT?, dtype: int64
从输出可以看出OT?数据集中的字段有 1151 个空值和 79 个非空值。
3>处理空值——fillna
fillna() 函数可以用任何指定的值填充空位。
以下代码在 OT? 字段为“0OT”,注释字段中的空值为“无处”。
dataset=dataset['OT?'].fillna('0OT')
dataset=dataset['Notes'].fillna('Nowhere')
#在处理空值之后,我们可以打印出前五行数据,看看原先是'NaN'的位置现在的值是什么
print(dataset.ix[:5])
# 输出结果为:
Date Score Type Visitor Team VisitorPts \
0 Tue Oct 29 2013 Box Score Orlando Magic 87
1 Tue Oct 29 2013 Box Score Los Angeles Clippers 103
2 Tue Oct 29 2013 Box Score Chicago Bulls 95
3 Wed Oct 30 2013 Box Score Brooklyn Nets 94
4 Wed Oct 30 2013 Box Score Atlanta Hawks 109
Home Team HomePts OT? Notes
0 Indiana Pacers 97 0OT Nowhere
1 Los Angeles Lakers 116 0OT Nowhere
2 Miami Heat 107 0OT Nowhere
3 Cleveland Cavaliers 98 0OT Nowhere
4 Dallas Mavericks 118 0OT Nowhere
(二)本关任务
在这个级别,我们为您提供鸢尾花数据集。数据集共有五个字段,分别是:
sepal.lengthsepal.widthpetal.lengthpetal.widthvariety
除了品种字段的内容是字符串外,其他字段的内容都是浮点数。您将完成的任务包括:
注意:pandas 中的平均值可以使用 mean() 函数计算。
示例: data['a'].means() 的结果是 a 字段的平均值。
(三)参考代码
import pandas as pd
dataset = pd.read_csv('iris.csv')
def count_nan(dataset):
'''
返回值:
[n1,n2,n3,n4,n5]
分别代表dataset的五列各有多少空值
'''
# 请在此添加代码 完成本关任务
# ********** Begin *********#
[n1, n2, n3, n4, n5] = dataset.isnull().sum()
# ********** End **********#
# 返回[n1,n2,n3,n4,n5]
return [n1, n2, n3, n4, n5]
def deal_nan(dataset):
'''
返回值:
dataset:按要求处理过、已经没有空值的数据
'''
# 请在此添加代码 完成本关任务
# ********** Begin *********#
dataset['sepal.length'] = dataset['sepal.length'].fillna(
dataset['sepal.length'].mean())
dataset['sepal.width'] = dataset['sepal.width'].fillna(
dataset['sepal.width'].mean())
dataset['petal.length'] = dataset['petal.length'].fillna(
dataset['petal.length'].mean())
dataset['petal.width'] = dataset['petal.width'].fillna(
dataset['petal.width'].mean())
dataset['variety'] = dataset['variety'].fillna('Unknown')
# ********** End **********#
# 返回dataset
return dataset
二、资料采集实战1.单网页爬取(一)相关知识
为了完成这个任务,需要几个基本技能。首先,你需要对 Python 语言有一定的掌握。了解 urllib 库、re 库、random 库。其中rrllib库主要实现网页的爬取。re 库实现了数据的正则化表示。随机库实现数据的随机生成。
1> 爬虫简介
网络爬虫是根据一定的规则自动爬取互联网信息的程序或脚本。爬虫的行为可以分为三个部分:
2> 网络爬虫
在使用Python进行数据爬取的过程中,我们首先需要了解爬虫的基本技能树,包括:静态网页采集、动态网页采集、爬虫框架设计和数据存储。
3> 网络爬虫:加载
加载是将目标网站数据下载到本地。主要步骤如下:
实际操作:抓取静态网页步骤
4> 网络爬虫:动态加载
有些页面的数据是动态加载的,比如Ajax异步请求。网页中的一些数据需要浏览器渲染或者用户的某些点击和下拉操作触发,即Ajax异步请求。
当面对动态加载的页面时,我们可以使用抓包工具分析某个操作触发的请求,并使用智能工具:selenium + webdriver,通过代码实现对应的请求。
5>网络爬虫:分析
从加载的结果中提取特定数据。加载的结果主要分为三类:html、json、xml。
(二)本关任务
请仔细阅读代码,结合相关知识,在Begin-End区补充代码,编写爬虫爬取网页标题。具体要求如下:
(三)参考代码
import urllib.request
import csv
import re
# 打开京东www.jd.com,读取并爬到内存中,解码, 并赋值给data
# 将data保存到本地
# ********** Begin ********** #
data = urllib.request.urlopen("https://www.jd.com").read().decode("utf-8", "ignore")
with open("./step1/京东.html", 'a') as f:
f.write(data)
# ********** End ********** #
# 使用正则提取title
# 保存数据到csv文件中
# ********** Begin ********** #
pattern = "(.*?)"
title = re.compile(pattern, re.S).findall(data)
with open("./step1/csv_file.csv", 'a') as f:
f_csv = csv.writer(f)
f_csv.writerow(title)
# ********** End ********** #
2.网页抓取策略(一)相关知识
主要介绍两种爬取策略:1.深度优先爬虫;2. 广度优先爬虫。
1> 深度优先爬虫(一路到底)
在网页中,当一个超链接被选中时,被链接的网页会进行深度优先搜索,即在搜索剩余的超链接结果之前,必须先完整搜索单个链接。深度优先搜索尽可能地跟踪网页上的超链接,然后返回到网页并继续选择该网页中的其他超链接。当没有其他超链接可供选择时,搜索结束。
例子:
爬取顺序为:1->2->4->8->5->3->6->7
2> 广度优先爬虫(逐层爬取)
广度优先爬取的过程从一系列*敏*感*词*节点开始,提取这些网页中的“子节点”,依次放入队列中进行爬取。处理后的链接需要放入表中。每次处理一个新的链接时,都需要检查该链接是否已经存在于表中。如果存在,则证明该链接已被处理,跳过,不处理,否则进行下一步。
例子:
爬取顺序为:1->2->3->4->5->6->7->8
(二)本关任务
请仔细阅读代码,结合相关知识,补充Begin-End区代码,编写爬虫实现深度优先爬虫。爬取的 网站 是。
(三)参考代码
<p>'''
' @author:ljq
' @date:2021/04/12
' @description
'
'''
from bs4 import BeautifulSoup
import requests
import re
class linkQuence:
def __init__(self):
# 已访问的url集合
self.visted = []
# 待访问的url集合
self.unVisited = []
# 获取访问过的url队列
def getVisitedUrl(self):
return self.visted
# 获取未访问的url队列
def getUnvisitedUrl(self):
return self.unVisited
# 添加到访问过得url队列中
def addVisitedUrl(self, url):
self.visted.append(url)
# 移除访问过得url
def removeVisitedUrl(self, url):
self.visted.remove(url)
# 未访问过得url出队列
def unVisitedUrlDeQuence(self):
try:
return self.unVisited.pop()
except:
return None
# 保证每个url只被访问一次
def addUnvisitedUrl(self, url):
if url != "" and url not in self.visted and url not in self.unVisited:
self.unVisited.insert(0, url)
# 获得已访问的url数目
def getVisitedUrlCount(self):
return len(self.visted)
# 获得未访问的url数目
def getUnvistedUrlCount(self):
return len(self.unVisited)
# 判断未访问的url队列是否为空
def unVisitedUrlsEnmpy(self):
return len(self.unVisited) == 0
class MyCrawler:
def __init__(self, seeds):
# 初始化当前抓取的深度
self.current_deepth = 1
# 使用*敏*感*词*初始化url队列
self.linkQuence = linkQuence()
if isinstance(seeds, str):
self.linkQuence.addUnvisitedUrl(seeds)
if isinstance(seeds, list):
for i in seeds:
self.linkQuence.addUnvisitedUrl(i)
print("Add the seeds url %s to the unvisited url list" %
str(self.linkQuence.unVisited))
################ BEGIN ##################
# 抓取过程主函数(方法一)
def crawling(self, seeds, crawl_deepth):
# 循环条件:抓取深度不超过crawl_deepth
while self.current_deepth