生为蝼蚁,应立鸿鹄之志,命如纸薄,当有不屈之心
今天的学习目标是组合数据类型
这个是爬虫的基础,元组(基本等价于C/C++中的数组)和字典在爬虫项目中用的非常多
1.基本统计值计算
def getNum(): # 获取用户不定长度的输入
nums = [] # 数组缓存
iNumStr = input("请输入数字(回车退出): ")
while iNumStr != "": # 不等于回车的时候就继续输入
nums.append(eval(iNumStr))
iNumStr = input("请输入数字(回车退出): ")
return nums # 返回这个数组
def mean(numbers): # 计算平均值
s = 0.0
for num in numbers:
s = s + num # 对数组进行遍历求和
return s / len(numbers) # 求平均值
def dev(numbers, mean): # 计算样本方差
sdev = 0.0 # 方差是在概率论和统计方差衡量随机变量或一组数据时离散程度的度量
for num in numbers:
sdev = sdev + (num - mean) ** 2 # 数组值和平均值差的平方和
print(pow(sdev / len(numbers), 0.5)) # 计算总体方差
return pow(sdev / (len(numbers) - 1), 0.5) # 计算样本方差
# 方差是衡量随机变量或一组数据时离散程度的度量
# 标准差、方差越大,离散程度越大
def median(numbers): # 计算中位数
sorted(numbers) # 先排序
size = len(numbers)
if size % 2 == 0: # 个数刚好为偶数
med = (numbers[size // 2 - 1] + numbers[size // 2]) / 2
# 个数为偶数,那么应该取中间两个数的平均数作为中位数
# 先看,size对2求整减1,size对2求整,这两个数,假设size为偶数4,那么这两个数为1和2,在数组中刚好为中间两个数
# 假设size为偶数6,那么这两个数为2和3,在数组中刚好为中间两个数
else: # 个数为奇数
med = numbers[size // 2] # 对2求整,加入数据加入个数为3,那么对2求整,刚好为1,在数组中刚好是第二个,正好在中间
# 假设加入数据加入个数为5,那么对2求整,刚好为2,在数组中刚好是第三个,正好在中间
# 假设加入数据加入个数为7,那么对2求整,刚好为3,在数组中刚好是第四个,正好在中间
return med
n = getNum() # 主体函数
m = mean(n) # 求平均值
print("平均值:{},方差:{:.2f},中位数:{}".format(m, dev(n, m), median(n)))
2.文本词频统计
def getText():
txt = open("hamlet.txt", "r").read()
txt = txt.lower()
for ch in '!"#$%&()*+,-./:;<=>?@[\\]^_‘{|}~':
txt = txt.replace(ch, " ") #将文本中特殊字符替换为空格
return txt
#这段数据清洗的代码在爬虫中非常常用,基本爬下来的数据都要做一下简单处理再用
hamletTxt = getText()#获取文本字符串
words = hamletTxt.split()#切片操作,将单词都分开存为数组
print(words)#这里可以看一下数组是什么
counts = {}#这里就用了字典,用word作为索引,其中把出现的次数作为value
for word in words:#对words数组所有的数据进行遍历
counts[word] = counts.get(word,0) + 1 #这里给索引添加值,每出现一次对应的单词,其值就+1
#.get赋初值初值为0
items = list(counts.items())#这里比较关键,将字典类型转换为数组
items.sort(key=lambda x:x[1], reverse=False)
#升序排序,这段可以理解为key被赋值为二维数组的每个元素的第二个值,
#假设lambda为f函数,则可以写成
def f(x):
return x[1]
#那么对应的这句排序代码就应该为:
items.sort(key=f(x), reverse=True)
#哈哈哈,当然这只是你想当然的,这里是没有X的,这句运行起来是一定会错的
#如果你是写C/C++的,你一定会忍不住写形参,哈哈哈,我也是
#真正的调用为下面的语句
items.sort(key=f, reverse=True)
for i in range(10):
word, count = items[i]#记住,这里的items是二维数组,这样的赋值没问题,这个方法也值得记住,再用的时候不陌生
print ("{0:<10}{1:>5}".format(word, count))
这段代码的hamlet.txt为全英语,其实任何英文文档都可以用这段代码处理,修改一下,很多数据清洗的场合都可以使用
import jieba
txt = open("threekingdoms.txt", "r", encoding='utf-8').read()
#words = jieba.lcut(txt,cut_all=False)#中文分词,精确模式
#words = jieba.lcut(txt,cut_all=True)#中文分词,全模式
words = jieba.lcut(txt)#中文分词
print(words)
counts = {}#计数字典
for word in words:#对数组进行遍历
if len(word) == 1:#如果这个字符长度为1,表示这个不是中文字符,不处理
continue
else:
counts[word] = counts.get(word,0) + 1#和之前的一样,给对应的索引添加数值
items = list(counts.items())#转换成数组
items.sort(key=lambda x:x[1], reverse=True)#降序排序
for i in range(15):#列出前15项
word, count = items[i]
print ("{0:<10}{1:>5}".format(word, count))
import jieba
excludes = {"将军","却说","荆州","二人","不可","不能","如此"}
txt = open("threekingdoms.txt", "r", encoding='utf-8').read()
words = jieba.lcut(txt)
counts = {}
for word in words:
if len(word) == 1:
continue
elif word == "诸葛亮" or word == "孔明曰":#列出别名,如果是这两个名字,就直接换名字
rword = "孔明"
elif word == "关公" or word == "云长":
rword = "关羽"
elif word == "玄德" or word == "玄德曰":
rword = "刘备"
elif word == "孟德" or word == "丞相":
rword = "曹操"
else:
rword = word#如果都不是这样的,就直接写
counts[rword] = counts.get(rword,0) + 1
for word in excludes:#如果有这个集合里面的数据,就直接删除counts里面的索引与值
del counts[word]
items = list(counts.items())#还是一样转换成数组,换了之后是二维的数组
print(items)
items.sort(key=lambda x:x[1], reverse=True)
for i in range(10):
word, count = items[i]#二维数组赋值,很重要的用法
print ("{0:<10}{1:>5}".format(word, count))
至此,今天复习目标达到,注释写完,程序有疑问的敲一遍,神清气爽,加油2021