当前位置:   article > 正文

Python学习过程问题记录(三):达内徐铭数据分析快速入门(2022年代码编译遇到的问题)

达内徐铭

目录


前言

电脑环境:macOS Monterey 12.2.1、Python3.10.2

工具:Sublime Text 4、Pycharm 2021.3(基本没用)

学习视频:达内教育徐铭2019年9月左右的数据分析课程,后面的人工智能课程没有学习。

虽然是2019年的课程,但大部分代码还是可用,只有少部分在我的环境中调试有问题,特此记录。

Python数据分析全套视频(由浅入深)_哔哩哔哩_bilibili

课件素材:下载地址       密码:USTC  (来源于B站up主-韭财的留言,视频和上面链接的一样,少了后面3个,但没有影响,最后3个也没听太懂)


问题一、matplotlib绘图的中文显示问题

第2天的matplotlib课程。

可能和老师的matplotlib版本不一样,显示的图片的设置少了一些,不过没有影响。

图形左下角的按钮比老师的少一点

后来开始想显示中文的时候出现了口口问题,解决方法参考我之前的记录:Python学习过程问题记录(二):Matplotlib中文显示问题


问题二、图形X轴时间总显示1970年

1.问题描述

第3天的3.13、3.14 numpy加载文件01、02课程。

代码如下,运行后图形X轴应该显示2011年,但却显示了1970年。

  1. import datetime as dt
  2. import matplotlib.dates as md
  3. import matplotlib.pyplot as mp
  4. import numpy as np
  5. # 日期转换函数
  6. def dmy2ymd(dmy):
  7. dmy = str(dmy, encoding='utf-8')
  8. time = dt.datetime.strptime(dmy, '%d-%m-%Y').date()
  9. t = time.strftime('%Y-%m-%d')
  10. return t
  11. # 读取数据
  12. dates, opening_prices, highest_prices, lowest_prices, closing_prices = np.loadtxt(
  13. '../da_data/aapl.csv',
  14. delimiter=',',
  15. usecols=(1, 3, 4, 5, 6), # 读取13456列 (下标从0开始)
  16. dtype='U10,f8,f8,f8,f8', # 制定返回每一列数组中元素的类型
  17. unpack=True, # 按列拆包
  18. converters={1: dmy2ymd}
  19. )
  20. # 绘制dates与收盘价的折线图
  21. mp.figure('AAPL K', facecolor='lightgray')
  22. mp.title('AAPL K')
  23. mp.xlabel('Date', fontsize=12)
  24. mp.ylabel('Closing Price', fontsize=12)
  25. mp.grid(linestyle=':')
  26. # 拿到坐标轴
  27. ax = mp.gca()
  28. # 设置主刻度定位器为周定位器(每周一显示主刻度文本)
  29. ax.xaxis.set_major_locator(md.WeekdayLocator(byweekday=md.MO))
  30. ax.xaxis.set_major_formatter(md.DateFormatter('%d %b %Y'))
  31. # 设置次刻度定位器为日定位器
  32. ax.xaxis.set_minor_locator(md.DayLocator())
  33. mp.tick_params(labelsize=8)
  34. dates = dates.astype(md.datetime.datetime)
  35. print(dates)
  36. mp.plot(dates, closing_prices, color='dodgerblue',
  37. linestyle='-', label='AAPL')
  38. mp.gcf().autofmt_xdate()
  39. mp.legend(loc=1)
  40. mp.show()

图形X轴日期显示错误

2.问题原因

通过和运行出正确图形的代码对比,发现问题出在:读取文件数据时将dates的类型设为了U10,字符串格式经过datetime.datetime转换不能正常显示日期。

3.解决方法

  • 第一种:在读取文件时就直接设置数据类型为日期类型M8[D]。
  1. # 错误设置
  2. ...
  3. dtype='U10,f8,f8,f8,f8',
  4. ...
  5. # 正确设置
  6. ...
  7. dtype='M8[D],f8,f8,f8,f8',
  8. ...
  • 第二种:读取文件时dates类型可以设置为字符串U10,但在后面通过astype()将类型转换成M8[D]。
  1. ...
  2. dates = dates.astype('M8[D]') # 将数据类型U10转换成M8[D]
  3. dates = dates.astype(md.datetime.datetime)
  4. mp.plot(...)
  5. ...

两种方法修改后,绘制图形的X轴日期均能正常显示。

图形X轴日期正常显示

问题三、一个括号造成的合成方波差别

1.问题描述

第6天的6.10 三角函数通用函数课程。

代码如下绘制图像时,虽然没有报错,但绘制出的图像和老师的不一样。

  1. import matplotlib.pyplot as mp
  2. import numpy as np
  3. x = np.linspace(-2 * np.pi, 2 * np.pi, 1000)
  4. y1 = 4 * np.pi * np.sin(x)
  5. y2 = 4 / 3 * np.pi * np.sin(3 * x)
  6. y3 = 4 / 5 * np.pi * np.sin(5 * x)
  7. # 叠加正弦函数,合成方波
  8. y = np.zeros(x.size)
  9. print(x.size)
  10. for i in range(1, 1000):
  11. y += 4 / ((2 * i - 1) * np.pi) * np.sin((2 * i - 1) * x)
  12. mp.grid(linestyle=':')
  13. mp.plot(x, y1, label='y1', alpha=0.2)
  14. mp.plot(x, y2, label='y2', alpha=0.2)
  15. mp.plot(x, y3, label='y3', alpha=0.2)
  16. mp.plot(x, y, label='y')
  17. mp.legend()
  18. mp.show()
我绘制的图像
老师绘制的图像
老师绘制的图像

2.问题原因

通过代码比对,唯一的不同就是我的多了一个括号:

  • 我的: y += 4 / ((2 * i - 1) * np.pi) * np.sin((2 * i - 1) * x)
  • 老师的: y += 4 / (2 * i - 1) * np.pi * np.sin((2 * i - 1) * x)

3.问题分析

一个括号造成一个pi在分母,一个pi在分子,这个完全是粗心问题。


问题四、AttributeError: module 'scipy.misc' has no attribute 'imread'

1.问题描述

第6天的6.11特征值和特征向量课程。

部分代码如下,编译出现错误:AttributeError: module 'scipy.misc' has no attribute 'imread'。

  1. import numpy as np
  2. import matplotlib.pyplot as mp
  3. import scipy.misc as sm
  4. ...
  5. # 读取图片,RGB格式
  6. original = sm.imread('../da_data/lily.jpg',True)
  7. # 提取特征值
  8. img = np.mat(original)
  9. eigvals, eigvecs = np.linalg.eig(img)
  10. ...

2.问题原因

scipy在新版本中misc库中弃用了一部函数,其中就包括imread,imresize和imsave

  • 可以降低scipy的版本,使用还支持imread的版本,如scipy1.2.1版本。
  • 使用的别的模块代替,我这里使用的是matplotlib.pyplot模块的imread读取图像。

但运行仍存在问题,对读取的图片提取特征量时显示错误:ValueError: shape too large to be a matrix。因为:

  • 使用original = sm.imread('../da_data/lily.jpg',True) 读取的图像是灰度图,original.shape是(512,512)。
  • 使用original = mp.imread('../da_data/lily.jpg') 读取的图像是RGB图,original.shape是(512,512,3)

所以需要将读取的RGB图转换为灰度图,使得图像的shape是(512,512)。

3.解决方法

定义一个RGB图转换为灰度图的函数,代码如下。

  • 0.299、0.587、0.114是设置RGB中加权平均值作为gray。
  • 这三个加权值可以自己设置权重,也可以使用RGB的平均值、最大值等,方法可网络搜索。
  1. def rgb2gray(rgb): # 将RGB格式转换为灰度模式
  2. return np.dot(rgb[...,:3], [0.299, 0.587, 0.114])
  3. original1 = rgb2gray(original)

经过这样的转换以后,再提取特征值,就不会报错了。

完整代码如下,绘制图片如图。

  • 但通过函数转换的灰度图直接使用mp.imshow(original1)绘制的图像并不是灰度图,显示颜色比较奇怪,需加上cmap参数才能正常显示灰度图:mp.imshow(original1,cmap='gray')
  1. import numpy as np
  2. import matplotlib.pyplot as mp
  3. mp.rcParams['font.sans-serif'] = 'Microsoft Yahei' # 显示汉字
  4. mp.rcParams['axes.unicode_minus'] = False
  5. # 读取图片,RGB格式
  6. original = mp.imread('../da_data/lily.jpg')
  7. print(original.shape,type(original),original.dtype,original.size)
  8. # 将RGB格式转换为灰度模式
  9. def rgb2gray(rgb):
  10. return np.dot(rgb[...,:3], [0.299, 0.587, 0.114])
  11. original1 = rgb2gray(original)
  12. # 提取特征值
  13. img = np.mat(original1)
  14. print(original1.shape)
  15. eigvals, eigvecs = np.linalg.eig(img)
  16. # 抹掉一部分特征值,生成新图片
  17. eigvals[50:] = 0
  18. dst1 = eigvecs * np.diag(eigvals) * eigvecs.I
  19. eigvals[30:] = 0
  20. dst2 = eigvecs * np.diag(eigvals) * eigvecs.I
  21. eigvals[10:] = 0
  22. dst3 = eigvecs * np.diag(eigvals) * eigvecs.I
  23. mp.subplot(231)
  24. mp.title('读取原图',fontsize=10)
  25. mp.xticks([])
  26. mp.yticks([])
  27. mp.imshow(original)
  28. mp.tight_layout()
  29. mp.subplot(232)
  30. mp.title('转换灰度模式',fontsize=10)
  31. mp.xticks([])
  32. mp.yticks([])
  33. mp.imshow(original1)
  34. mp.tight_layout()
  35. mp.subplot(233)
  36. mp.title("转换灰度模式(cmap='gray')",fontsize=10)
  37. mp.xticks([])
  38. mp.yticks([])
  39. mp.imshow(original1,cmap='gray')
  40. mp.tight_layout()
  41. mp.subplot(234)
  42. mp.title('抹掉部分特征值\n(保留50特征值)',fontsize=10)
  43. mp.xticks([])
  44. mp.yticks([])
  45. mp.imshow(dst1.real,cmap='gray') # 必须加.real不然报错
  46. mp.tight_layout()
  47. mp.subplot(235)
  48. mp.title('抹掉部分特征值\n(保留30特征值)',fontsize=10)
  49. mp.xticks([])
  50. mp.yticks([])
  51. mp.imshow(dst2.real,cmap='gray') # 必须加.real不然报错
  52. mp.tight_layout()
  53. mp.subplot(236)
  54. mp.title('抹掉部分特征值\n(保留10特征值)',fontsize=10)
  55. mp.xticks([])
  56. mp.yticks([])
  57. mp.imshow(dst3.real,cmap='gray') # 必须加.real不然报错
  58. mp.tight_layout()
  59. mp.show()
绘制的图片

问题五、matplotlib.pyplot 有个子图不显示(tight_layout()问题)

1.问题描述

第7天的7.11杂项之图像课程。

代码如下,但绘制出的图像有个子图不显示。

  1. import numpy as np
  2. import matplotlib.pyplot as mp
  3. import scipy.ndimage as sn
  4. mp.rcParams['font.sans-serif'] = 'Microsoft Yahei' # 显示汉字
  5. mp.rcParams['axes.unicode_minus'] = False
  6. #读取文件
  7. original = mp.imread('../da_data/lily.jpg', True)
  8. # 将RGB格式转换为灰度模式
  9. def rgb2gray(rgb):
  10. return np.dot(rgb[...,:3], [0.299, 0.587, 0.114])
  11. img = rgb2gray(original)
  12. #高斯模糊
  13. median = sn.median_filter(img, 21)
  14. #角度逆时针旋转45度
  15. rotate = sn.rotate(img, 45)
  16. #边缘识别
  17. prewitt = sn.prewitt(img)
  18. mp.figure('图像',facecolor='lightgray')
  19. mp.subplot(221)
  20. mp.imshow(img, cmap='gray')
  21. mp.title('原图变灰度图',fontsize=10)
  22. mp.xticks([])
  23. mp.yticks([])
  24. mp.tight_layout()
  25. mp.subplot(222)
  26. mp.imshow(median, cmap='gray')
  27. mp.title('高斯模糊',fontsize=10)
  28. mp.xticks([])
  29. mp.yticks([])
  30. mp.tight_layout()
  31. mp.subplot(223)
  32. mp.imshow(rotate, cmap='gray')
  33. mp.title('角度旋转',fontsize=10)
  34. mp.xticks([])
  35. mp.yticks([])
  36. mp.tight_layout()
  37. mp.subplot(224)
  38. mp.imshow(prewitt, cmap='gray')
  39. mp.title('边缘识别',fontsize=10)
  40. mp.xticks([])
  41. mp.yticks([])
  42. mp.tight_layout()
  43. mp.show()
其中一个子图不显示

2.问题原因

只知道是使用了mp.tight_layout()的原因,可以参考一下帖子。matplotlib之pyplot模块——调整子图布局(subplots_adjust、tight_layout)

tight_layout函数概述
tight_layout函数的功能为子图的内边距。备注:对axes()函数生成的子图无效。

函数的签名为matplotlib.pyplot.tight_layout(*, pad=1.08, h_pad=None, w_pad=None, rect=None)

函数的参数如下:

pad:所有子图整体边缘相对于图像边缘的内边距,距离单位为字体大小的比例(小数,与rcParams["font.size"]相关)。可选参数。浮点数。默认值为1.08。
h_pad, w_pad:子图之间的内边距,距离单位为字体大小的比例(小数)。可选参数。浮点数。默认值为pad。
rect:绘制子图的矩形区域的归一化坐标。可选参数。4元组(left, bottom, right, top)。默认值为(0, 0, 1, 1)。

3.解决方法

将不显示的那个子图mp.subplot(223)的紧凑布局代码mp.tight_layout()注释掉,修改后如下:

  1. ...
  2. mp.subplot(223)
  3. mp.imshow(rotate, cmap='gray')
  4. mp.title('角度旋转',fontsize=10)
  5. mp.xticks([])
  6. mp.yticks([])
  7. # mp.tight_layout() # 注释掉此句代码,该子图即可正常显示

另外试了一下,设置mp.tight_layout的w_pad参数大于4也可以显示,但显示效果不如不使用tight_layout好。

绘制的图像正常显示:

子图正常显示

总结

以上就是数据分析这8天的学习过程遇到的问题。

第99~101个视频的2.2、2.3、2.4项目实战:项目环境配置等课程,因为没有Ubuntu环境没有进行学习。

声明:本文内容由网友自发贡献,不代表【wpsshop博客】立场,版权归原作者所有,本站不承担相应法律责任。如您发现有侵权的内容,请联系我们。转载请注明出处:https://www.wpsshop.cn/w/我家小花儿/article/detail/142311
推荐阅读
相关标签
  

闽ICP备14008679号