《Python编程-从入门到实践》16.2.6收盘价均值详解

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


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

Python中的zip(), zip()与zip(zip(a,b))


接下来先上代码:
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, <itertools._grouper object at 0x01D704F0>) (3, <itertools._grouper object at 0x01E6D0E8>) (5, <itertools._grouper object at 0x01E6D268>)
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的新手, 所以写得比较详细. 希望能帮助到大家, 如果我的文章中有什么错误或者不准确的地方, 也欢迎大家勘误, 大家共同学习.

©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 204,921评论 6 478
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 87,635评论 2 381
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 151,393评论 0 338
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 54,836评论 1 277
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 63,833评论 5 368
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 48,685评论 1 281
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 38,043评论 3 399
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 36,694评论 0 258
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 42,671评论 1 300
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 35,670评论 2 321
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 37,779评论 1 332
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 33,424评论 4 321
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 39,027评论 3 307
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 29,984评论 0 19
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 31,214评论 1 260
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 45,108评论 2 351
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 42,517评论 2 343