关于《python编程从入门到实践》P332收盘价均值小结中绘图代码函数报错问题

《python编程从入门到实践》的第16章的16.2.6 收盘价均值小节运行报错,书中并没有像以往内容一样对用到的函数有说明,而且完全按照书中代码敲上去却还是出现报错:object of type ‘int’ has no len(),对于初学者来说真的是一脸蒙圈。

# 将数据加载到一个列表中
filename = 'btc_close_2017.json'
with open(filename) as f:
    btc_data = json.load(f)
 
dates = []
months = []
weeks = []
weekdays = []
close = []

# 每一天的信息
for btc_dict in btc_data:
    dates.append(btc_dict['date'])
    months.append(int(btc_dict['month']))
    weeks.append(int(btc_dict['week']))
    weekdays.append(btc_dict['weekday'])
    close.append(int(float(btc_dict['close'])))

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]):  # 1
        y_list = [v for _, v in y]
        xy_map.append([x, sum(y_list) / len(y_list)])  # 2
    x_unique, y_mean = [*zip(*xy_map)]  # 3
    line_chart = pygal.Line()
    line_chart.title = title
    line_chart.x_labels = x_unique # 4 
    line_chart.add(y_legend, y_mean)
    line_chart.render_to_file(title + '.svg')
    return line_chart

idx_month = dates.index('2017-12-01')
line_chart_month = draw_line(
    months[:idx_month], close[:idx_month], '收盘价月日均值(¥)', '月日均值')
line_chart_month

首先,传入实参x_data为1~11月的月份数,打印到屏幕上可见:在这里插入图片描述
y_data为对应的收盘价格。

#1中使用zip()函数将x_data和y_data打包成元组列表,即[(1,6928), (1,7070) … 省略 … (11,65583)],在python 3 中zip()返回的是一个支持遍历的对象,如果此时打印该返回值,会出现<zip object at 0x1007096c8>错误。
接着使用sorted()函数进行排序,返回一个排序后的元组列表,即[(1, 5383), (1,5566) … 省略 … (1,6928), (1,7070) … 省略… (11,65583)]。使用 groupby()来进行分组,key=lambda _: _[0]代表按照元组列表中的第一个元素进行分类(如果是[1]则是按照第二个),可被分为11组,x是分类的key值,x为1~11,y是对应的元组。
1 [(1,5383), (1,5566) … 省略 … (1,7835)]
2 [(2,6793), (2,6811) … 省略 … (2,8206)]

y_list = [v for _,v in y]
将元组中的收盘价格的值取出来,再计算其均值,sum(y_list) / len(y_list)是每月对应的均值。

#2 将月份数以及对应的收盘值月均值储存到xy_map[],此时xy_map的值为[[1, 6285.870967741936], [2, 7315.714285714285], [3, 7789.032258064516], [4, 8390.466666666667], [5, 12963.935483870968], [6, 18092.166666666668], [7, 17146.16129032258], [8, 26092.645161290322], [9, 26865.633333333335], [10, 35460.67741935484], [11, 51436.166666666664]]

#3 *zip相当于解压,zip(*xy_map)将原列表解压为[(1,2,3,4,5,6,7,8,9,10,11),(6285.870967741936, 7315.714285714285, 7789.032258064516, 8390.466666666667, 12963.935483870968, 18092.166666666668, 17146.16129032258, 26092.645161290322, 26865.633333333335, 35460.67741935484, 51436.166666666664) ]。最后[*zip(*xy_map)]使其成功赋值给x_unique,和y_mean。至此,已经将数据分类成功,x_unique的值为(1,2,3,4,5,6,7,8,9,10,11),y_mean的值为(6285.870967741936, 7315.714285714285, 7789.032258064516, 8390.466666666667, 12963.935483870968, 18092.166666666668, 17146.16129032258, 26092.645161290322, 26865.633333333335, 35460.67741935484, 51436.166666666664)。

#4 x_unique的值数据类型是int, line_chart.x_labels需要的类型是str,因此会出现报错: object of type ‘int’ has no len()。只需要修改#2处的代码,在此处将x转换成str类型即可,代码如下:

xy_map.append([str(x), sum(y_list) / len(y_list)])  # 2
  • 18
    点赞
  • 15
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值