Python练习(六)
目录
词云
股票分析
习题
词云
描述
词云,也叫文字云,是一种应用广泛的数据可视化方法。是过滤掉文本中大量的低频信息,形成“关键词云层”或“关键词渲染”,对出现频率较高的“关键词”予以视觉化的突出展现,使浏览者只要一眼扫过文本就可领略文本的主旨。
word_cloud是python的一个第三方库,可根据文本或文本中的词频,对文本内容进行可视化。(需通过指令pip install wordcloud安装)
word_cloud生成词云的主要方法有如下三种,分别用于以词频为参数或以字符文本为参数的场景。
| generate_from_frequencies(frequencies) fit_words(frequencies) | 根据词频生成词云,参数为包含词与词频的字典。 |
| generate_from_text(text) generate(text) | 根据文本生成词云,如果参数是排序的列表,需设置“collocations=False”,否则会导致每个词出现2次。 |
| process_text(text) | 将英文长文本text分词并去除屏蔽词后生成词云。 |
请按照如下要求,依次绘制对应的词云图:
1. 根据文件“Who Moved My Cheese.txt”的内容,用词频为参数的方法绘制英文词云,设置背景色为白色,不显示坐标轴。

2. 根据文件“Who Moved My Cheese.txt”的内容,用文本为参数的方法绘制英文词云,设置背景色为白色,不显示坐标轴。观察两种方法绘制结果,分析其原因,了解stopwords参数的意义及stopwords文件的内容,思考用词频方法时,怎样处理才能得到与文本方法相近的结果?

3. 中文词之间无分隔,所以中文词云的制作略麻烦,需要提前对文本进行分词处理。jieba是目前应用较广泛的一个中文分词库,可以导入jieba利用它进行分词再绘制词云。
import jieba
import jieba.analysejieba.analyse.textrank(sentence, topK=20, withWeight=False, allowPOS=('ns', 'n', 'vn', 'v'))
应用textrank()方法对字符串进行分词,可用参数topK设置最多返回多少个词(词性表allowPOS默认仅提取词性为地名ns、名词n、动名词vn、动词v),例如设置topK=100,返回最多100个词。返回的词与其权值以元组类型作为列表的元素,按权值降序排列,数据格式如:
[('科技', 1.0), ('创新', 0.6818768373499384), ('研究', 0.39785607069634815), ('科学家', 0.39327521713414126), ...]
将这个列表转为字典类型, 利用WordCloud.generate_from_frequencies()方法,以词频作参数,便可以绘制中文词云了。读文件“scientist.txt”,根据内容生成词云,字体不限,但要求中文能正常显示。设置用前60个高频词生成词云,背景色为白色,用“ball.jpg”作背景图片或自选背景图片。

输入输出示例
无,词云图效果参考上面的例图,以附件形式上传绘制的图片。
import string
import jieba.analyse
import wordcloud
from wordcloud import WordCloud
import matplotlib.pyplot as pltdef read_file(file):"""接收文件名为参数,将文件中的内容读为字符串,只保留文件中的英文字母和西文符号,过滤掉中文,所有字符转为小写,将其中所有标点、符号替换为空格,返回字符串。"""# =======================================================# 此处去掉注释符号“#”并补充你的代码with open('Who Moved My Cheese.txt','r') as f:str=''.join(i for i in f.read() if ord(i) < 256)for i in str:if i in string.punctuation:str=str.replace(i,'')elif i=='\n':str=str.replace('\n',' ')return str.lower()# =======================================================def word_frequency(txt):"""@参数 txt:去除标点、符号的文本,字符串接收去除标点、符号的字符串,统计并返回每个单词出现的次数。返回值为字典类型,单词为键,对应出现的次数为值。"""# =======================================================# 此处去掉注释符号“#”并补充你的代码dic={}for i in txt.split():dic[i]=dic.get(i,0)+1return dic# =======================================================def draw_cloud_en_freq(en_frequency):"""@参数 en_frequency:词频,字典类型绘制词云,传入参数为词频,设定图片的宽度600,高度400,背景白色、字体最大值150、图片边缘为5。"""# =======================================================# 此处去掉注释符号“#”并补充你的代码wc=wordcloud.WordCloud(width=600,height=400,max_font_size=150,margin=5,background_color='white')wc.generate_from_frequencies(en_frequency)wc.to_file('en_freq.png')# =======================================================def draw_cloud_en_txt(text):"""@参数 text:读文件获取的文本,字符串绘制词云,传入参数为文本(字符串),设定图片的宽度600,高度400,背景白色、字体最大值150、图片边缘为5。"""# =======================================================# 此处去掉注释符号“#”并补充你的代码wc = wordcloud.WordCloud(width=600, height=400, max_font_size=150, margin=5, background_color='white')wc.generate(text)wc.to_file('en_txt.png')# =======================================================def read_file_cn(file):"""接收文件名为参数,将文件中的内容读为字符串"""# =======================================================# 此处去掉注释符号“#”并补充你的代码with open('scientist.txt','r',encoding='utf-8') as f:return f.read()# =======================================================def word_frequency_cn(txt):"""@参数 txt:读文件获取的文本,字符串传入参数为读文件获取的文本字符串。jieba.analyse.textrank()可用参数topK设置最多返回多少个按词频降序排列的关键词列表,数据格式为列表:[('人民', 1.0), ('中国', 0.9533997295396189), ...]将列表转为字典:{'人民': 1.0, '中国': 0.9533997295396189,...},返回这个字典,字典的键是关键词,值是关键词的权值。"""# =======================================================# 此处去掉注释符号“#”并补充你的代码dic={}for k, v in jieba.analyse.textrank(txt, topK=60, withWeight=True, allowPOS=('ns', 'n', 'vn', 'n')):dic[k]=vreturn dic# =======================================================def draw_cloud_cn(frequency_dict):"""@参数 frequency_dict:词频,字典类型接收词频字典为参数,用'ball.jpg'做词云背景。利用matplotlib中的imread('ball.jpg')从图像文件读入数据,得到一个表示图像的NumPy数组。"""# =======================================================# 此处去掉注释符号“#”并补充你的代码im=plt.imread('ball.jpg')wc = wordcloud.WordCloud(mask=im,font_path='msyh.ttc',background_color='white')wc.generate_from_frequencies(frequency_dict)wc.to_file('cn.png')# =======================================================if __name__ == '__main__':filename = 'Who Moved My Cheese.txt' # 英文文件名filename_cn = 'data/scientist.txt' # 用于生成词云的中文文件名content = read_file(filename) # 调用函数返回字典类型的数据frequency_result = word_frequency(content)draw_cloud_en_freq(frequency_result)draw_cloud_en_txt(content)content_cn = read_file_cn(filename_cn)frequency = word_frequency_cn(content_cn) # 利用jieba对文本进行分词,并统计词频draw_cloud_cn(frequency) # 绘制词云
string.punctuation
返回一个包含所有标点符号的字符串,一般用于字符串常量的预初始化
>>> import string
>>> print(string.punctuation)
!"#$%&'()*+,-./:;<=>?@[\]^_`{|}~
jieba库中的analyse.textrank()
jieba.analyse.textrank(txt, topK=5,withWeight=True, allowPOS=('ns', 'n', 'vn', 'v'))
txt(string):待提取关键词的文本
topK(int):按权重(频率)从高到低,返回关键词的数量
withWeight(bool):是否同时返回每个关键词的权重;若设置为True,则需使用以关键字为key,以关键字对应的权重为value的字典接收
allowPOS:词性过滤,默认为('ns', 'n', 'vn', 'v'),分别为地名、名词、动名词、动词
参考博客:https://www.cnblogs.com/1061321925wu/p/12518541.html
wordcloud库中的generate_from_frequencies()
generate_from_frequencies的参数为词频字典,词频字典基本组成为为以字符串为key,以整形为value
generate与generate_from_frequencies()的区别
generate的参数为字符串,而generate_from_frequencies的参数为字典;并且generate使用空格区分词语
股票分析
描述
附件每个文件名对应股票代码的股票交易数据,使用这些文件进行运算并输出结果,如跌幅最大的10支股票代码的集合、成交量最大的10支股票代码集合、最高价最高的10支股票代码的集合、最低价最低的10支股票代码集合等。(为方便统计,本题中涨跌幅计算公式设定为:(最新记录收盘价-最早记录收盘价) / 最早记录收盘价 * 100。)
(注意:第一个函数未使用,在代码区域写pass,只占位置,不起作用。全部文件下载后放到data文件夹中,测试用的python文件也放到data文件夹中。)
Date: 日期
High: 最高价
Low: 最低价
Open: 开盘价
Close: 收盘价
Volume: 成交量
交易数据文件数据内容格式为:
Date,High,Low,Open,Close,Volume,Adj Close
2018-01-02,5.929999828338623,5.829999923706055,5.860000133514404,5.909999847412109,10649302.0,5.6797099113464355
2018-01-03,5.989999771118164,5.820000171661377,5.880000114440918,5.909999847412109,14893773.0,5.6797099113464355
2018-01-04,5.889999866485596,5.829999923706055,5.869999885559082,5.849999904632568,9974470.0,5.622048854827881
2018-01-05,5.880000114440918,5.820000171661377,5.849999904632568,5.849999904632568,6584055.0,5.622048854827881
2018-01-08,5.929999828338623,5.860000133514404,5.860000133514404,5.920000076293945,11096694.0,5.689321041107178
... ...
根据用户输入,利用集合运算和这些文件数据完成以下任务:
输入'涨幅与成交量'时,参考示例格式输出:
涨幅和成交量均在前10名的股票:
涨幅或成交量在前10名的股票:
涨幅前10名,但成交量未进前10名的股票:
涨幅和成交量不同时在前10名的股票:
输入'涨幅与最高价'时,参考示例格式输出:
涨幅和最高价均在前10名的股票:
涨幅或最高价在前10名的股票:
涨幅前10名,但最高价未进前10名的股票:
涨幅和最高价不同时在前10名的股票:
输入'跌幅与最低价'时,参考示例格式输出:
跌幅和最低价均在前10名的股票:
跌幅或最低价在前10名的股票:
跌幅前10名,但最低价未进前10名的股票:
跌幅和最低价不同时在前10名的股票:
输入其他数据时,输出:'输入错误'
输入输出示例
示例仅为格式展示,输出数据非真实分析结果。
示例 1
输入:
涨幅与成交量
输出:
涨幅和成交量均在前10名的股票:
['600000', '600019', '600031', '600036']
涨幅或成交量在前10名的股票:
['600000', '600004', '600006', '600030', '600031', '600033', '600036']
涨幅前10名,但成交量未进前10名的股票:
['600004', '600006', '600009', '600033']
涨幅和成交量不同时在前10名的股票:
['600004', '600026', '600028', '600029', '600033']
示例 2
输入:涨幅
输出:输入错误
import os
import numpy as np# 设置常量,对应各列数据的语义,方便索引
HIGH = 0
LOW = 1
OPEN = 2
CLOSE = 3
VOLUME = 4
ADJCLOSE = 5# def file_list(file):
# """
# @参数 file: 文件名,字符串类型
# 将文件中的股票代码与股票名称读入到字典中,返回股票代码字典。
# ['600000', '600004', '600006', '600007', '600008', '600009',...]
# """
# 下面代码区域随便放pass或一个没有语法错误的语句就可以,只占位置,不起作用
# 点击在此输入代码def statistics_of_all(code_list):"""@参数 code_list:股票代码列表,列表类型接收股票数据文件名列表,逐个统计各股票数据文件涨跌幅、总成交量、最高价和最低价。涨跌幅计算公式为:(最新记录收盘价-最早记录收盘价) / 最早记录收盘价 * 100为方便处理,读入数据时,略过日期列。"""statistics_of_stock = []for code in code_list:data_of_code = np.genfromtxt(code, dtype=None,usecols=[1, 2, 3, 4, 5, 6], delimiter=',',skip_header=1)# 计算当前股票涨跌幅、总成交量、最高价和最低价uplift_or_fall = round((data_of_code[:, CLOSE][-1] - data_of_code[:, CLOSE][0]) / data_of_code[:, CLOSE][0] * 100, 2)volumes = round(sum(data_of_code[:, VOLUME]), 2)high = round(max(data_of_code[:, HIGH]), 2)low = round(min(data_of_code[:, LOW]), 2)statistics_of_stock.append([code[:6], uplift_or_fall, volumes, high, low])return statistics_of_stock # 每支股票涨跌幅、总成交量、最高价和最低价def top_10_uplift(statistics_of_stock):"""@参数 statistics_of_stock:每支股票涨跌幅、总成交量、最高价和最低价统计信息,列表类型按涨幅降序排序,涨幅相同时按股票代码降序排序,取排名前10的股票,返回排名前10的股票代码,返回值为列表类型。"""sort_by_uplift = sorted(statistics_of_stock, key=lambda x: (x[1], x[0]), reverse=True)[:10]top_uplift = [x[0] for x in sort_by_uplift]print(top_uplift)return top_upliftdef top_10_fall(statistics_of_stock):"""@参数 statistics_of_stock:每支股票涨跌幅、总成交量、最高价和最低价统计信息,列表类型按跌幅升序排序,跌幅相同时,按股票代码升序排序,取排名前10的股票,返回跌幅最大的10支股票代码的集合。"""sort_by_fall = sorted(statistics_of_stock, key=lambda x: (x[1], x[0]))[:10]top_fall = [x[0] for x in sort_by_fall]return top_falldef top_10_volumes(statistics_of_stock):"""@参数 statistics_of_stock:每支股票涨跌幅、总成交量、最高价和最低价统计信息,列表类型按成交量降序排序,成交量相同时,按股票代码降序排序,取成交量前10的股票代码,返回成交量最大的10支股票代码列表。"""sort_by_volumes = sorted(statistics_of_stock, key=lambda x: (x[2], x[0]),reverse=True)[:10]top_volumes = [x[0] for x in sort_by_volumes]return top_volumesdef top_10_high(statistics_of_stock):"""@参数 statistics_of_stock:每支股票涨跌幅、总成交量、最高价和最低价统计信息,列表类型按最高价降序排序,最高价相同时,按股票代码降序排序返回,取排名前10的股票,返回最高价最高的10支股票代码的列表。"""sort_by_high = sorted(statistics_of_stock, key=lambda x: (x[3], x[0]),reverse=True)[:10]top_high = [x[0] for x in sort_by_high]return top_highdef top_10_low(statistics_of_stock):"""@参数 statistics_of_stock:每支股票涨跌幅、总成交量、最高价和最低价统计信息,列表类型按最低价升序排序,最低价相同时,按股票代码升序排序,取排名前10的股票,返回最低价最低的10支股票代码集合。"""sort_by_low = sorted(statistics_of_stock, key=lambda x: (x[4], x[0]))[:10]top_low = [x[0] for x in sort_by_low]return top_lowdef uplift_and_volumes(top_uplift, top_volumes):"""@参数 top_high,最高价在前10名的股票代码,字符串@参数 top_volumes,成交量在前10名的股票代码,字符串返回一个列表,其元素依序为以下4个:涨幅和成交量均在前10名的股票,按股票代码升序,列表涨幅或成交量在前10名的股票,按股票代码升序,列表涨幅前10名,但成交量未进前10名的股票,按股票代码升序,列表涨幅和成交量不同时在前10名的股票,按股票代码升序,列表"""both_of = sorted(set(top_uplift) & set(top_volumes))any_of = sorted(set(top_uplift) | set(top_volumes))uplift_no_volumes = sorted(set(top_uplift) - set(top_volumes))uplift_or_volumes = sorted(set(top_uplift) ^ set(top_volumes))# print(both_of,any_of,uplift_no_volumes,uplift_or_volumes)return [both_of,any_of,uplift_no_volumes,uplift_or_volumes]def high_and_uplift(top_uplift, top_high):"""@参数 top_high,最高价在前10名的股票代码,字符串@参数 top_uplift,涨幅在前10名的股票代码,字符串返回一个列表,其元素依序为以下4个:涨幅和最高价均在前10名的股票代码,按股票代码升序,列表涨幅或最高价在前10名的股票代码,按股票代码升序,列表涨幅前10名,但最高价未进前10名的股票代码,按股票代码升序,列表涨幅和最高价不同时在前10名的股票,按股票代码升序,列表票代码。"""both_of = sorted(set(top_uplift) & set(top_high))any_of = sorted(set(top_uplift) | set(top_high))uplift_no_high= sorted(set(top_uplift) - set(top_high))uplift_or_high = sorted(set(top_uplift) ^ set(top_high))return [both_of, any_of, uplift_no_high, uplift_or_high]def low_and_fall(top_fall, top_low):"""@参数 top_low,最低价在前10名的股票代码,字符串@参数 top_fall,跌幅在前10名的股票代码,字符串返回一个列表,其元素依序为以下4个跌幅和最低价均在前10名的股票代码,按股票代码升序,列表跌幅或最低价在前10名的股票代码,按股票代码升序,列表跌幅前10名,但最低价未进前10名的股票代码,按股票代码升序,列表跌幅和最低价不同时在前10名的股票,按股票代码升序,列表"""both_of = sorted(set(top_fall) & set(top_low))any_of = sorted(set(top_fall) | set(top_low))fall_no_low = sorted(set(top_fall) - set(top_low))fall_or_low = sorted(set(top_fall) ^ set(top_low))return [both_of, any_of, fall_no_low, fall_or_low]def operation():"""接收一个字符串为参数,根据参数值调用不同函数完成任务"""statistics_of_list = statistics_of_all(stock_lst) # 对获取的股票数据进行统计uplift_set = top_10_uplift(statistics_of_list) # 涨幅前10名集合fall_set = top_10_fall(statistics_of_list) # 跌幅前10名集合volumes_set = top_10_volumes(statistics_of_list) # 成交量前10名集合high_set = top_10_high(statistics_of_list) # 最高价前10名集合low_set = top_10_low(statistics_of_list) # 最低价前10名集合opt = input()if opt == '涨幅与成交量': # 输出抽中的单词u_and_v = uplift_and_volumes(uplift_set, volumes_set)print('涨幅和成交量均在前10名的股票:')print(u_and_v[0]) # 涨幅和成交量均在前10名的股票print('涨幅或成交量在前10名的股票:')print(u_and_v[1]) # 涨幅或成交量在前10名的股票print('涨幅前10名,但成交量未进前10名的股票:')print(u_and_v[2]) # 涨幅前10名,但成交量未进前10名的股票print('涨幅和成交量不同时在前10名的股票:')print(u_and_v[3]) # 涨幅和成交量均在前10名的股票elif opt == '涨幅与最高价':h_and_u=high_and_uplift(uplift_set,high_set)print('涨幅和最高价均在前10名的股票:')print(h_and_u[0]) # 涨幅和成交量均在前10名的股票print('涨幅或最高价在前10名的股票:')print(h_and_u[1]) # 涨幅或成交量在前10名的股票print('涨幅前10名,但最高价未进前10名的股票:')print(h_and_u[2]) # 涨幅前10名,但成交量未进前10名的股票print('涨幅和最高价不同时在前10名的股票:')print(h_and_u[3]) # 涨幅和成交量均在前10名的股票elif opt == '跌幅与最低价':l_and_f=low_and_fall(fall_set,low_set)print('跌幅和最低价均在前10名的股票:')print(l_and_f[0]) # 涨幅和成交量均在前10名的股票print('跌幅或最低价在前10名的股票:')print(l_and_f[1]) # 涨幅或成交量在前10名的股票print('跌幅前10名,但最低价未进前10名的股票:')print(l_and_f[2]) # 涨幅前10名,但成交量未进前10名的股票print('跌幅和最低价不同时在前10名的股票:')print(l_and_f[3]) # 涨幅和成交量均在前10名的股票else:print('输入错误')if __name__ == '__main__':# filename = './data/沪市股票top300.csv' # 股票名称与代码文件stock_lst = ['600000.csv', '600004.csv', '600006.csv','600007.csv', '600008.csv', '600009.csv','600010.csv', '600011.csv', '600012.csv','600015.csv', '600016.csv', '600018.csv','600019.csv', '600020.csv', '600026.csv','600028.csv', '600029.csv', '600030.csv','600031.csv', '600033.csv', '600036.csv']operation()
习题
1.x轴的取值范围为-π到π,间隔为π/6。依次计算它们的正弦、余弦、正切,并在一张图中绘制子图,排列为一行三列(采用subplot函数)。并且,上述每个子图显示x、y轴刻度,子图标题等,采用三种不同颜色绘制。
import numpy as np
import matplotlib.pyplot as plt
from matplotlib.pyplot import MultipleLocatorpi=np.pi
x=np.linspace(-pi,pi)
xaxis=round(pi/6,2)
sin=np.sin(x)
cos=np.cos(x)
tan=np.tan(x)plt.figure(figsize=(30,3))ax_sin=plt.subplot(131).plot(x,sin,'r')
plt.grid(True)
plt.title('sin(x)')
plt.gca().xaxis.set_major_locator(MultipleLocator(xaxis))ax_cos=plt.subplot(132).plot(x,cos,'g')
plt.grid(True)
plt.title('cos(x)')
plt.gca().xaxis.set_major_locator(MultipleLocator(xaxis))ax_tan=plt.subplot(133).plot(x,tan,'b')
plt.grid(True)
plt.title('tan(x)')
plt.gca().xaxis.set_major_locator(MultipleLocator(xaxis))plt.show()
numpy库中的linspace
numpy.linspace(start, stop, num)
start:控制数值范围的起始点
stop:控制数值范围的终止点
num:控制数值序列中有多少个元素,如num=5,则值序列中5个元素(数组长度为5)
pyplot库中的方法
plot():绘制函数
plot(x, y, ls='-', lw=2, label='plot figure',color='g' )
x: x轴上数值序列
y: y轴上数值序列
ls:线条风格 (linestyle)
lw:线条宽度 (linewidth)
label:该绘制内容在图中的标签文本
color:线条颜色
参考博客:https://blog.csdn.net/qq_40520596/article/details/105298663
title():设置图像标题
import matplotlib.pyplot as plt
#plt.plot(x,y) 需先创建图像对象
#...
plt.title('str')
grid():显示网格线
import matplotlib.pyplot as plt
#plt.plot(x,y) 需先创建图像对象
#...
plt.grid(True)
subplot():绘制子图
subplot(numRows, numCols, plotNum)
整个figure被分成numRows行,numCols列,plotNum参数指定创建的子图所在的区域
import matplotlib.pyplot as plt
#plt.plot(x,y) 需先创建图像对象
#...
#整个figure被分成1*3块
plt.subplot(131) # 使用1*3中的第1个区域(1行1列)
plt.subplot(132) # 使用1*3中的第2个区域(1行2列)
plt.subplot(133) # 使用1*3中的第2个区域(1行3列)
plt.show()
import matplotlib.pyplot as plt
#plt.plot(x,y) 需先创建图像对象
#...
#整个figure被分成2*2块
plt.subplot(221) # 使用2*2中的第1个区域(1行1列)
plt.subplot(222) # 使用2*2中的第2个区域(1行2列)
plt.subplot(212) # 将2*2块重新划分为2*1块,并使用2*1中的第2个区域(2*1中的第1个区域已被前两个使用)
plt.show()
2.自定义手绘风。修改实例17,使手绘效果更符合你的审美特点(请写出你的绘制风格思路)。
from PIL import Image
import numpy as npvec_el=np.pi/2.2
vec_az=np.pi/4.depth=10
im=Image.open('scene.png').convert('L')
a=np.asarray(im).astype('float')
grad=np.gradient(a)
grad_x,grad_y=grad
grad_x=grad_x*depth/100.
grad_y=grad_y*depth/100.
dx=np.cos(vec_el)*np.cos(vec_az)
dy=np.cos(vec_el)*np.sin(vec_az)
dz=np.sin(vec_el)
A=np.sqrt(grad_x**2+grad_y**2+1.)
uni_x=grad_x/A
uni_y=grad_y/A
uni_z=1./A
a2=255*(dx*uni_x+dy*uni_y+dz*uni_z)
a2=a2.clip(0,255)
im2=Image.fromarray(a2.astype('uint8'))
im2.save('HandDraw.jpg')
本文来自互联网用户投稿,文章观点仅代表作者本人,不代表本站立场,不承担相关法律责任。如若转载,请注明出处。 如若内容造成侵权/违法违规/事实不符,请点击【内容举报】进行投诉反馈!
