python平均入门时间_《Python编程-从入门到实践》16-2-6收盘价均值详解

因为书里关于代码的解释部分一直都写得比较详细, 但是到了这一小段后突然说得很省略, 并且引用了几个之前未使用过的函数, 例如zip(), *zip(), lambda, groupby等. 自己也是花了不少时间才把这个代码搞懂, 故记录下来, 既是加深记忆, 也希望能帮到同样有疑惑的同学.

这里面主要是zip()和*zip()函数比较让人费解, 为了避免重复, 大家可先看我的这篇文章, 详细了解这两个函数(其实是同一个函数), 然后再看代码就比较容易懂了.

接下来先上代码:

from itertools import groupby

def draw_line(x_data, y_data, title, y_legend):

xy_map = []

for x, y in groupby(sorted(zip(x_data, y_data)), key=lambda _:_[0]):

y_list = [v for _, v in y]

xy_map.append([x, sum(y_list) / len(y_list)])

x_unique, y_mean = [*zip(*xy_map)]

line_chart = pygal.Line()

line_chart.title = title

line_chart.x_labels = x_unique

line_chart.add(y_lengend, y_mean)

line_chart.render_to_file(title+'.svg')

return line_chart

逐行解释:

第1行: 引入迭代工具groupby, 从itertools中引出出来的函数都是迭代器, 想获得其中的数据, 需要用for循环或者其余访问方式获取, 所以下面的draw_line中, 使用了for循环获取其中的数据.

第3行: 定义了draw_line方法, 其中4个参数分别为, 月份, 该月收盘价, 图表标题, 图例. 因为该表用到的数据是若干年的数据, 所以每个月会有不定数量的该月数据, 如10个3月的数据.

第4行: 创建了一个空列表

第5~7行: 重中之重, 下面按嵌套顺序解释:

zip(x_data, y_data): 把月份和该月的收盘价结合成一个二元元素(一个含有2个值的元素). 例如: x_data = [1,2,3,1], y_data =[1200,1400,1300,1450]. 由于在数据文件中, 他们的元素序列都是一一对应的, 使用zip后, 就变成了(1,1200), (2,1400), (3,1300), (1,1450). (假设比较小的数字便于讲解, 真实文件里的数据不为如此)

sorted的算法是先根据第一个元素进行排序, 第一个元素相同则根据第二个元素排序, 所以排列后的数字为(1,1200), (1,1450), (2,1400), (3,1300). sorted后的数据变成了按照月份的升序排列, 把他称为sorted_object

接下来进行groupby分组函数, 分组的依据由key决定, 而key则使用了lambda函数, lambda是个匿名函数, 其相当于

def functionA(_):

return _[0] # 也就是无论你给他什么参数, 他都给你返还这个参数索引为0的数.**

而且, key具体函数的参数取自于可迭代对象中,指定可迭代对象中的一个元素进行排序. 也就是把可迭代对象sorted_object作为参数, 传递给lambda函数, 然后进行分组, 分组的依据为第0号索引的元素, 即元素中的第一个数, 如(1,1200)中的1.

排序后进行分组, 其数据形式会变成这样: (1, ((1,1200),(1, 1450))), (2, (2,1400)), (3, (3,1300)), 也就是元素第一个数是组号, 第二个数是多个二元元素. 所以此时for循环里x代表的是组号, y代表的是后面的多个二元元素集合

代码举例:

A = (1,400), (3,600), (5,700), (1,900), (1,500), (3,800)

print(*groupby(sorted(A),key=lambda _:_[0]))

for x,y in groupby(sorted(A),key=lambda _:_[0]):

for x1, y1 in y:

print(x1,y1)

---

输出结果:

(1, ) (3, ) (5, )

1 400

1 500

1 900

3 600

3 800

5 700

所以图形代码第6行里, [v for _,v in y]中, (_和v)是一个整体,分别代表第一个数和第二个数, 但是y_list只取第二个数收盘价用于运算, 使用列表解析取出了同一个月的所有收盘价数据

第7行: sum(y_list) / len(y_list), 总和除以数据个数求出均值, 再和x组合成元素, 此时的x虽是组号, 但是因为我们把1月分成第一组, 2月分成第二组, 所以该组号也是月份数, 于是xy_map列表由各月月数和该月平均收盘价组成. 如:[(1, 1203), (2, 1340), (3, 1245)]等

第8行: [*zip(*xy_map)], 逐层来看, *xy_map, 把上面的[(1, 1203), (2, 1340), (3, 1245)]变成了(1, 1203), (2, 1340), (3, 1245)的多个二元元素, *号的作用就是把列表的[ ]去掉了(详看开头的第一篇文章), 然后对这些元素进行一次zip()操作, 就会得到(1, 2, 3), (1203, 1340, 1245), 但是由于此时的zip是迭代对象, 他的值不能直接取出, 所以需要再在前面加一个*号, 并且用[ ]将其包裹起来, 让两个多元元素分别作为列表的0号和1号元素赋给x_unique和y_mean. 此时x_unique是月份数, y_mean是各月的收盘均值, 下面就可以进行绘图了

第9~14行: 都是比较简单的代码, 大略提一下, 分别为: 创建折线图, 添加标题, 设置x轴刻度, 添加折线图数据, 保存图像, 将折线图作为方法返回值.

考虑到学这本书的应该都是和我一样刚接触python的新手, 所以写得比较详细. 希望能帮助到大家, 如果我的文章中有什么错误或者不准确的地方, 也欢迎大家勘误, 大家共同学习.

  • 2
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值