《Python编程从入门到实践》16.2中,计算收盘价均值的程序有些不易看懂,结合我自己的理解进行一些说明。
使用的数据集:join格式的数据,
数据集是由多个字典为元素组成的列表。每个字典包含如下信息
[{
"date": "2017-01-01",
"month": "01",
"week": "52",
"weekday": "Sunday",
"close": "6928.6492"
}......
{
"date": "2017-12-12",
"month": "12",
"week": "50",
"weekday": "Tuesday",
"close": "113732.6745"
}]
计算均值的程序为:
跳过函数,从idx_month = dates.index('2017-12-01')看起,index函数为返回列表的索引值,看下面例子:
因此,这部分代码意为,首先让集合了所有日期的列表dates用index方法取2017-12-01这一天的索引,并将其赋给idx_month,之后months[:idx_month], closes[:idx_month]表示分别对日期列表months,收盘价列表closes进行切片处理,取到了索引从0到idx_months的所有值,也就是2017-12-01这一天之前的所有日期,以及对应的收盘价,并将其和另外两个实参传递到函数draw_line中。下面对函数中的每个语句进行说明。
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]):
#zip(x_data, y_data)表示将传入的日期列表months和收盘价列表closes,分别按顺序各取一个元素打包成元组列表组合成一个新的迭代器——zip类,即[(1,6928), (1,7070) …… (11,65583)]。
第二层的sorted函数对元组列表进行排序,得到了按照月份从小到大,同一月份的收盘价从小到大排序的元组列表[(1, 5383), (1,5566) …… (1,6928), (1,7070) …… (11,65583)]。这里sorted函数先把第一位从小到大排好,再排第二位,以此类推。
第三层的groupby函数,是一个分组聚合函数,key=lambda _: [0]是用匿名函数Lambda(Lambda表达式基于数学中的λ演算得名)表示的条件。
lambda函数:
lambda 参数列表: 对参数需要进行的操作
key=lambda _: _[0]就表示取列表中索引为[0]的值,并将返回值赋给key(下划线表示临时变量,仅用一次之后销毁),key这个表达式表示groupby分组的依据,意味着按照元组列表的第一个元素进行分类。每循环一次,得到一组数据,x就是分类的key值。最后循环十一次,x=1~11,y则是对应的元组列表,得到:
x: 1 y: [(1,5383), (1,5566) …… (1,7835)]
2 [(2,6793), (2,6811) …… (2,8206)]
……
y_list = [v for _, v in y]
#下划线表示没有用到的值,这里即为y中元组的第一个值,将每个月的收盘价添加到y_list中
xy_map.append([x, sum(y_list) / len(y_list)])
#计算每个月的收盘价均值,并将元素以(月份,均值)的格式添加到空列表中。
x_unique, y_mean = [*zip(*xy_map)]
#*zip(iterable)函数是zip函数的逆过程,可将zip函数处理后的结果恢复为之前的样子。*可理解为解压。看例子:
所以它将xy_map中每个元组中的第一个元素全部取出,赋给x_unique,得到x_unique=(1,2,3,4,5,6,7,8,9,10,11),第二个元素全部取出,赋给y_mean,得到y_mean=(6285.870967741936, 7315.714285714285, 7789.032258064516, 8390.466666666667, 12963.935483870968, 18092.166666666668, 17146.16129032258, 26092.645161290322, 26865.633333333335, 35460.67741935484, 51436.166666666664)。
line_chart = pygal.Line()
#设置画的图为折线图格式
line_chart.title = title
#设置标题
line_chart.x_labels = x_unique
#设置x轴的标签
line_chart.add(y_legend, y_mean)
#加入y轴的数据及其它的含义
line_chart.render_to_file(title + '.svg')
#存储图片
return line_chart
#返回该图片
参考资料:CSDN-专业IT技术社区-登录 这篇博客也进行了详细的讲解。