数据分析与NumPy
与课程相关的AI使用技巧
- 电脑的基本操作,例如:如何安装某个软件,如何设置打印机,如何安装显卡驱动,如何打开某些系统组件等等
举例:Windows如何显示文件拓展名
2、创建命令行命令,例如:不熟悉的命令行工具,我们可以让AI为我们创建命令
举例:使用yt-dlp下载整个播放列表的音频,选择最佳音频质量,将其转换为160kbps的MP3文件,忽略下载错误,并以视频标题作为文件名保存。
3、解释命令参数,例如:遇到不了解的命令,让AI给我们解释参数的含义,以及整个命令的功能
举例:给我解释这行命令的含义:ffmpeg -i input.mp4 -vf scale=480:-1 -c:v libx265 output.mp4
4、通过AI学习配置虚拟环境,例如:列出conda所有的虚拟环境,列出虚拟环境装所安装的软件包版本,如何升级conda环境中的软件包,删除虚拟环境等等 举例:列出虚拟环境装所安装的软件包版本
5、使用AI大模型学习Python第三方库,例如: 可以这样问AI:我想做数据分析,应该学习哪个Python库? 让AI讲解NumPy的核心概念,能给我展示一下如何使用Matplotlib库来绘制图表吗? 在使用Django开发Web应用时,有哪些最佳实践? 我想用BeautifulSoup库来解析HTML,你能教我怎么做吗? 我在使用SciPy库时遇到某某错误,你可以帮我分析可能的原因和解决方案吗?
举例:我是一个Python新手,我该如何学习NumPy
6、使用AI生成代码,例如:让AI按我们的需求生成代码 举例:帮我使用Python的pygame库,编写一个贪吃蛇的游戏 7、使用AI解释代码,例如:遇到不明白的代码,让AI解释
举例:给我解释这段代码:
from datetime import datetime
today_date = str(datetime.now().date().strftime(“%Y%m%d”))
def date_difference(date1, date2=today_date):
# 将字符串日期转换为日期对象
d1 = datetime.strptime(date1, “%Y%m%d”)
d2 = datetime.strptime(date2, “%Y%m%d”)
delta = abs(d2 - d1) difference = delta.days
return difference
date1 = “20240901”
date2 = “20240925”
print(f”两个日期之间的天数差是:{date_difference(date1, date2)} 天”)
8、使用AI注释代码,例如:让AI给代码生成注释,方便理解
举例:给这段代码生成注释
5 数据分析基础
5.1 数据收集
数据收集是研究过程中获取信息和数据的关键步骤,它可以通过多种方法进行。以下是几种主要的数据收集方法的简要介绍:
- 问卷法:通过设计调查问卷,向研究对象收集结构化的数据。通常用于大样本的定量研究。
- 实验法:在控制条件下进行实验,观察变量的变化,获取因果关系的数据。多用于自然科学和部分社会科学研究。
- 观察法:研究者通过直接观察对象的行为或现象,获取真实环境下的定性数据。
- 采访/访谈法:通过与研究对象的面对面或电话交流,获取深入的主观信息。多用于探索性和质性研究。
- 文献法:通过查阅已有的文献、档案或数据,收集历史或背景信息,通常用于理论研究或对比分析。
5.2 数据预处理
很多原始数据在收集之后是不能直接应用的,这些数据会存在各种各样的问题影响使用,这些数据被成为“脏数据”。“脏数据”出现的问题一般可分为以下几种。
- 数据重复:数据集中存在重复记录,可能导致偏差或过拟合。通常需要去重,以确保数据的独立性和准确性。
- 异常值:数据中的极端值或偏离大多数数据的观测值,可能是由于测量错误或特殊情况。异常值可能影响模型的表现,处理方式包括删除、修改或重新定义这些值。
- 数据缺失:部分数据字段没有值(NaN)。常见处理方法有删除含缺失值的样本、用均值/中位数填充、插值法、或使用专门处理缺失值的算法。
- 数据不均衡:分类任务中,某些类别的样本数量远多于其他类别,导致模型倾向于预测多数类。常见处理方法包括过采样、欠采样或使用特殊的损失函数来处理不均衡数据。
- 数据噪声:数据中的随机误差或不可解释的波动,可能影响模型的准确性。去噪技术如滤波、平滑、或者选择更鲁棒的模型可以减少噪声的影响。
例如: 假设你是一家零售公司的分析师,你需要分析过去一年内每个月的销售额数据,以确定销售趋势。然而,由于季节性因素、促销活动、经济波动等因素的影响,每个月的销售额数据都包含一定程度的噪声。
以下是原始数据(单位:万元):
1月: 150
2月: 200
3月: 180
4月: 220
5月: 210
6月: 300
7月: 280
8月: 260
9月: 240
10月: 230
11月: 250
12月: 270
你注意到6月和7月的数据明显高于其他月份,这可能是由于夏季促销活动导致的。为了更准确地分析销售趋势,你需要减少这种由于促销活动引起的噪声。
步骤1:分箱处理 你决定使用等宽分箱处理,将一年分为四个季度,每个季度包含三个月:
第一季度:1月、2月、3月
第二季度:4月、5月、6月
第三季度:7月、8月、9月
第四季度:10月、11月、12月
步骤2:计算统计量 对于每个季度,你计算销售额的平均值:
第一季度平均销售额:(150 + 200 + 180) / 3 = 183.33
第二季度平均销售额:(220 + 210 + 300) / 3 = 240
第三季度平均销售额:(280 + 260 + 240) / 3 = 260
第四季度平均销售额:(230 + 250 + 270) / 3 = 248.33
步骤3:平滑处理 使用平均值后,你得到了一个更平滑的销售趋势:
第一季度: 183.33
第二季度: 240
第三季度: 260
第四季度: 248.33
数据预处理的方法一般有:数据清理、数据集成、数据规约和数据变换。
数据清理:一般指的是通过填补缺失值、删除异常数据、平滑数据等手段处理数据集中的一些”脏数据”。
- 对于缺少值:如果缺失的属性太多,便可以删除数据。当缺失的属性比较少并且属性不是特别重要时,可以选择填充它们。填充的数据一般使用均值或者中位数。 - 对于离群点、异常值:需要先对数据进行判定。常见的判定方法有简单的统计分析、正态分布判定、基干距离、基于聚类等。
- 对干异常点:通常选择删除处理,一些特殊情况下可以使用平均值 或者中位数代替。
- 对于噪声(噪声是指那些不代表真实信号的随机波动或异常值。噪声可能来源于测量误差、数据录入错误、随机过程等。):通常的解决方式是使用等频或等宽进行分箱处理。使用平均值、中位数或者边界值进行平滑。
数据集成:是将多个来源的数据放在一起存储。在数据集成的过程中会遇到取值冲突、冗余等问题。所以一般数据集成后会对数据进行二次处理。
数据规约:一些数据集的规模较大,需要通过技术手段降低数据规模。一般有维度规约 和维度变换两种方法。数据集中的数据有很多属性,但是会有一些我们不需要的,维度约束则是去 除这些不需要的冗余属性。维度变换是将现有数据降低到更小的维度,尽量保证数据信息的完整性, 它不改变属性的多少。
数据变化:一般是对数据进行变换使得更加规范、稀疏化。一般用得最多的有以下几种变换。
最大-最小规范化:将数据通过最大-最小规范化公式映射到[0,1]区间。最大-最小规范化公式为:

Score标准化,将数据减去均值除以方差,公式为:

5.3 数据分析
数据分析是一系列从原始数据中提取有用信息和知识的过程,它涉及数据清洗、转换、建模和解释,旨在发现模式、趋势和关联,以支持决策制定、优化业务流程和提高运营效率。通过使用统计分析、机器学习、数据挖掘和可视化技术,数据分析可以帮助组织从大量数据中获得洞察力,并将其转化为可操作的策略。
5.4 数据可视化
数据可视化是一种将数据转换为图形或图像表示的技术,它通过图表、地图、交互式仪表板和其他视觉工具来呈现复杂数据集,使得信息更加直观易懂,帮助用户快速识别模式、趋势和异常,从而促进更有效的沟通和决策。通过直观展示数据,数据可视化不仅增强了数据的可访问性和吸引力,还加强了数据驱动的洞察力和发现。
5.5 数据应用
数据应用是指将数据分析、处理和可视化的成果转化为实际的业务决策、产品优化、市场策略或政策制定的过程。它涉及利用数据驱动的洞察来指导行动,解决具体问题,提高效率,增强客户体验,或创造新的商业机会。在数据应用中,数据科学家、分析师和业务决策者通常会使用先进的分析模型、机器学习算法和大数据处理技术,将原始数据转化为可执行的策略和解决方案,从而在金融、医疗、教育、零售等多个领域实现数据的商业价值和社会影响力。
6 Numpy与矩阵乘法
6.1 矩阵乘法
二维矩阵乘法:
假设矩阵A是一个2行 x 3列的矩阵,矩阵B是一个3行 x 2列的矩阵,矩阵A乘以矩阵B得到结果矩阵C: 那么A x B就是矩阵A的第一行的3个元素分别与矩阵B第一列的3个元素分别相乘,然后求和,就得到矩阵C的第一行第一列的元素,其余元素以此类推: image.png 因此应该一个 m行 × n列 的矩阵,乘以一个 n行 × p列 的矩阵,那么 A * B 的结果将是一个 m行 × p列 的矩阵。 且计算矩阵A乘以矩阵B时,要求矩阵A的列数等于矩阵B的行数,否则无法计算。 矩阵乘法有以下特点: - 不满足交换律 AB ≠ BA - 满足结合律 (AB)C = A(BC)
练习: 
答案:
C11=1*7+2*10=27
C12=1*8+2*11=30
C13=1*9+2*12=33
C21=3*7+4*10=61
C22=3*8+4*11=68
C23=3*9+4*12=75
C31=5*7+6*10=95
C32=5*8+6*11=106
C33=5*9+6*12=117
[[ 27, 30, 33],
[ 61, 68, 75],
[ 95, 106, 117]]
#使用nympy计算矩阵乘法:
import numpy as np
A = [[1, 2],
[3, 4],
[5, 6]]
B = [[7, 8, 9],
[10, 11, 12]]
r = np.array(A)@np.array(B)
r
三位矩阵乘法:
假设有两个三维矩阵:
A = [[[ 1, 2, 3], [ 4., 5, 6]], [[ 7, 8, 9], [10, 11, 12]]]
B = [[[ 1, 2], [ 3, 4], [ 5, 6]],]
A矩阵如图所示: 
我们可以把3维矩阵看成是2个二维矩阵堆叠在一起:



得到的结果为: [[[ 22, 28], [ 49, 64]], [[220, 244], [301, 334]]]
如何学习使用第三方库:
Python在众多领域都有大量优秀的第三方库,
例如:
数据科学:NumPy、Pandas、Matplotlib 图像处理:Pillow、OpenCV
网络爬虫:Requests
Web 开发:Django、Flask
机器学习:scikit-learn、TensorFlow、Keras
深度学习:Pytorch
元认知:不是掌握知识,而是掌握学习知识的方法
学习并掌握第三方库的方法:
- 通过官方文档中的快速入门指南或教程学习
举例: NumPy quickstart:https://numpy.org/doc/stable/user/quickstart.html
- 使用搜索引擎查找相关案例
举例: 通过搜索引擎查询:https://www.bing.com/search?q=numpy+%E6%96%B0%E6%89%8B%E6%95%99%E7%A8%8B
3、通过AI大模型进行学习
举例: 向AI大模型提问:“给我讲解NumPy的核心概念”,“使用NumPy创建一个3行4列的随机矩阵”,“给我解释这行代码:a = np.floor(10*np.random.rand(3,4))”
6.2 NumPy的介绍与安装
NumPy简介: NumPy是Python中的一个开源库,主要用于科学计算和数据处理。它提供了支持多维数组(ndarray)的强大功能,并拥有丰富的数学、统计和线性代数运算函数。NumPy的主要作用是高效地处理大规模数据,包括数组操作、矩阵运算、数值计算等。其核心是高性能的多维数组对象,广泛应用于数据分析、机器学习、图像处理等领域,为其他科学计算库(如Pandas和TensorFlow)提供了基础。 NumPy安装: pip install numpy
6.3 NumPy基础
参考链接:https://numpy.org/doc/stable/user/quickstart.html NumPy的主要用于创建和处理多维数组。 NumPy的数组类型(class)是ndarray,也被成为array。ndarray对象的一些重要属性如下: ndarray.ndim:数组的维度。 ndarray.shape:表示数组在每个维度上的大小。对于一个有 n 行和 m 列的矩阵,其形状将是 (n, m)。 ndarray.size:数组中元素的总数。 ndarray.dtype:数组中元素的对象类型。可以使用标准Python类型来创建或指定dtype。此外,NumPy还提供了自己的类型。numpy.int32、numpy.int16和numpy.float64。 ndarray.itemsize:数组中每个元素的字节大小(每个字节为8位)。 ndarray.data:包含数组实际元素的缓冲区。通常,我们不需要使用这个属性,因为我们会使用索引功能来访问数组中的元素。
##An example
import numpy as np
a = np.arange(15).reshape(3, 5) #创建一个0-14的一维数组,然后将数组的形状修改为3行5列。
a
a.ndim
a.shape
a.dtype.name
a.itemsize
a.size
type(a)
b = np.array([6, 7, 8])
b
type(b)
6.4 创建数组
可以使用多种方法来创建数组,例如可以将Python的列表或元组传入array函数创建数组:
#使用array函数创建数组
import numpy as np
a = np.array([2, 3, 4])
print(a)
print(a.dtype)
b = np.array([1.2, 3.5, 5.1])
print(b.dtype)
a = np.array(1, 2, 3, 4) # 常见错误,传入了多个参数
a = np.array([1, 2, 3, 4]) # 正确,传入一个序列对象
a
#array函数将二次嵌套的序列转换成二维数组,将三次嵌套的序列转换成三维数组,以此类推。
b = np.array([(1.5, 2, 3), (4, 5, 6)])
b
#使用zeros函数,创建所有元素都为0的数组
np.zeros((3, 4))
#使用ones函数,创建所有元素都为1的数组
np.ones((2, 3, 4), dtype=np.int16)
#使用empty函数创建初始内容是随机值(随机值取决于内存的状态)的数组
np.empty((2, 3))
#使用arange函数创建序列数组
np.arange(0, 10, 1) #起始值,结束值(不包含),步进
#使用linspace函数生成等间隔的数字序列数组
np.linspace(0, 2, 9) #在0-2中,生成9个等间隔元素
6.5 数组的基础操作
对数组的算术运算符应用是逐元素进行的。其结果会创建一个新的数组。
#数组加减法
a = np.array([20, 30, 40, 50])
b = np.arange(4)
c = a - b #每个元素依次相减
print(a)
print(b)
print(c)
#数组乘法,每个元素依次乘2
print(b)
print(b**2)
#计算正弦值
#print(np.sin(20))
print(a)
print(10 * np.sin(a))
#比较数组元素大小
print(a)
print(a < 35)
# 逐元素乘法(Element-wise Multiplication):*运算符
A = np.array([[1, 1],
[0, 1]])
B = np.array([[2, 0],
[3, 4]])
A * B # 每个元素依次相乘
# 矩阵乘法(Matrix Multiplication):@运算符或者dot方法
A = np.array([[1, 1],
[0, 1]])
B = np.array([[2, 0],
[3, 4]])
print(A @ B) # 矩阵乘法
print(A.dot(B)) # 矩阵乘法的另一种形式
6.6 数组通用函数
B = np.arange(3)
B
#数组的e次方
np.exp(B)
#数组的开平方
np.sqrt(B)
#数组加法
B = np.array([0, 1, 2])
C = np.array([2., -1., 4.])
np.add(B, C)
6.7 数组的索引、切片与迭代
#索引与切片
a = np.arange(10)**3
print(a)
print(a[2]) #索引,从0开始计算
print(a[2:5]) #切片
#切片赋值
a[:6:2] = 1000 #从0开始,每间隔2的元素被赋值为1000
a
#将数组a反向排序
a[::-1] # 反转数组 a
#数组的遍历
for i in a:
print(i**(1 / 3.)) #遍历每个元素,然后开3次方根
#多维数组索引
b = np.array([[ 0, 1, 2, 3],
[10, 11, 12, 13],
[20, 21, 22, 23],
[30, 31, 32, 33],
[40, 41, 42, 43]])
b[2,3] #第3行第4个元素
b[0:5, 1] # 第0到第4行的第2个元素
b[:, 1] # 参数缺失时表示选择数组中的所有行,与b[0:5, 1]等效
b[1:3, :] # 第2行(从0计数)到第3行的所有列
b[-1] # 最后一行的所有列,等效于[-1, :]
#数组的迭代
b = np.array([[ 0, 1, 2, 3],
[10, 11, 12, 13],
[20, 21, 22, 23],
[30, 31, 32, 33],
[40, 41, 42, 43]])
for row in b:
print(row) #遍历行
for element in b.flat: #先将数组展成1维,然后遍历
print(element)
6.8 数组的形状操作
a = np.floor(10*np.random.rand(3,4))
a
a.shape #查看数组的形状
a.ravel() # 将数组展平
a.reshape(6, 2) #将数组的形状修改为6行2列,使用reshape会新建一个数组对象,不会修改原数组
a.T #数组行列转置
print(a.T.shape)
print(a.shape)
a.resize((2, 6)) #reshape不会修改原数组,resize直接修改原数组
a
6.9 20个NumPy小练习
参考链接:https://favtutor.com/blogs/numpy-exercises-python
练习一:两个数组的元素相加
a = np.array([[1,2,3],
[4,5,6]])
b = np.array([[10,11,12],
[13,14,15]])
c = a + b
print(c)
练习二:数组乘以标量
a = np.array([[1,2,3],
[4,5,6]])
b = 2*a # 将 数组a乘以 2
print(b)
练习三:创建一个4 x 4的单位矩阵(任何矩阵乘以单位矩阵都等于原矩阵)
i = np.eye(4)
print(i)
练习四:将一维数组转化为三维数组
a = np.array([x for x in range(27)])
o = a.reshape((3,3,3))
print(o)
练习五:将数组的所有元素由浮点数转化为整数
a = np.array([[2.5, 3.8, 1.5],
[4.7, 2.9, 1.56]])
o = a.astype('int')
print(o)
练习六:将二进制数组转化为布尔(Boolean)数组
a = np.array([[1, 0, 0],
[1, 1, 1],
[0, 0, 0]])
o = a.astype('bool')
print(o)
练习七:水平堆叠数组
a1 = np.array([[1,2,3],
[4,5,6]])
a2 = np.array([[7,8,9],
[10,11,12]])
o = np.hstack((a1, a2))
print(o)
练习八:垂直堆叠数组
a1 = np.array([[1,2],
[3,4],
[5,6]])
a2 = np.array([[7,8],
[9,10],
[10,11]])
o = np.vstack((a1, a2))
print(o)
练习九:使用序列对象创建数组,创建从0到100,间隔为2的数组
#方法一:
list_of_numbers = [x for x in range(0, 101, 2)]
o = np.array(list_of_numbers)
print(o)
#方法二:
o = np.arange(0, 101, 2)
print(o)
练习十:获取两个数组元素匹配的位置
a = np.array([1,2,3,4,5])
b = np.array([1,3,2,4,5])
print(np.where(a == b))
练习十一:使用linespace创建等间隔数组
o = np.linspace(0, 100, 5) #从0到100(不包含100),创建等间隔,包含5个元素的数组
print(o)
练习十二:使用特定的值创建矩阵
#方法一:
o = np.full((2, 3), 5)
print(o)
#方法二:
a = np.ones((2, 3))
o = 5*a
print(o)
练习十三:将一个二维小数组重复 10 次生成新的数组
a = np.array([[1,2,3],
[4,5,6]])
o = np.tile(a, 10)
print(o)
练习十四:指定范围内的随机整数生成数组
np.random.seed(123) # 设置随机数种子,通常情况下,计算机产生的“随机数”并非真正的随机,而是伪随机数。当设置相同的种子时,随机数生成器将每次产生相同的随机数序列。
o = np.random.randint(0, 10, size = (5,5))
print(o)
练习十五:使用符合正态分布的随机数生成数组
np.random.seed(123) # 设置随机数种子
o = np.random.normal(size = (3,3))
print(o)
练习十六:矩阵乘法
#方法一:
a = np.array([[1,2,3],
[4,5,6],
[7,8,9]])
b = np.array([[2,3,4],
[5,6,7],
[8,9,10]])
o = a@b
print(o)
#方法二:
a = np.array([[1,2,3],
[4,5,6],
[7,8,9]])
b = np.array([[2,3,4],
[5,6,7],
[8,9,10]])
o = np.matmul(a, b)
print(o)
练习十七:矩阵转置
a = np.array([[1,2,3],
[4,5,6],
[7,8,9]])
a_transpose = a.T #行列转置
print(a_transpose)
练习十八:计算弧度数组的正弦值
angles = np.array([3.14, 3.14/2, 6.28]) #分别对应180度,90度,360度
sine_of_angles = np.sin(angles)
print('Sine of the given array of angles = ', sine_of_angles)
练习十九:计算弧度数组的余弦值
angles = np.array([3.14, 3.14/2, 6.28])
cosine_of_angles = np.cos(angles)
print('Cosine of the given array of angles = ', cosine_of_angles)
练习二十:以升序排序生成数组索引
array = np.array([10,1,5,2])
indexes = np.argsort(array) #返回值[1 3 2 0],索引1为原数组最小值,索引3为原数组次小值,以此类推
print(indexes)
notebook链接:https://www.kaggle.com/code/jeanshendev/data-analysis-and-numpy