NumPy基础:数组和⽮量计算
参考:
[走在小路上]
4.1 NumPy的ndarray:⼀种多维数组对象
NumPy 是一个运行速度非常快的数学库,主要用于数组计算
- NumPy 是一个运行速度非常快的数学库,主要用于数组计算,包含:
- 一个强大的N维数组对象 ndarray
- 广播功能函数
- 整合 C/C++/Fortran 代码的工具
- 线性代数、傅里叶变换、随机数生成等功能
1、ndarry概述:
-
NumPy(Numerical Python的简称)是Python数值计算最重要 的基础包。⼤多数提供科学计算的包都是⽤NumPy的数组作为 构建基础。
-
多维数组对象,是同构数据,多维容器,也就是说,他的内容类型是相同的。
-
基于NumPy的算法要⽐纯Python快10到100倍(甚⾄更快),并 且使⽤的内存更少
-
.专门为大数据计算所诞生的
【注释:参考《书》P114】
2、Numpy数组类型:
int8、int16、int32、 float16、float32、float64等等
【注释:见《菜鸟教程》Numpy数据类型】
3、Numpy数组属性:
ndarray.ndim | 秩,即轴的数量或维度的数量 |
---|---|
ndarray.shape | 数组的维度,对于矩阵,n 行 m 列 |
ndarray.size | 数组元素的总个数,相当于 .shape 中 n*m 的值 |
ndarray.dtype | ndarray 每个元素类型 |
ndarray.itemsize | ndarray 对象中每个元素的大小,以字节为单位 |
ndarray.flags | ndarray 对象的内存信息 |
ndarray.real | ndarray元素的实部 |
ndarray.imag | ndarray 元素的虚部 |
ndarray.data | 包含实际数组元素的缓冲区,由于一般通过数组的索引获取元素,所以通常不需要使用这个属性。 |
【注释:参考《菜鸟教程》】
4、从已有的数组创建数组
-
※numpy.array():
import numpy as np score = np.array([[80, 89, 86, 67, 79], [78, 97, 89, 67, 81], [90, 94, 78, 67, 74], [91, 91, 90, 67, 69], [76, 87, 75, 67, 86], [70, 79, 84, 67, 84], [94, 92, 93, 67, 64], [86, 85, 83, 67, 80]]) print(type(score)) print(score.shape) print(score.dtype)
结果:
# 创建数组的时候指定类型 np.array([1.1, 2.2, 3.3], dtype="float32")
-
numpy.asarray(a, dtype = None, order = None)
类似 numpy.array:
x = [1,2,3] a = np.asarray(x)
data1 = np.array(score) # 深拷贝
data2 = np.asarray(score) # 浅拷贝 =======>比如对data2[0] = 111操作后,你打印score发现score[0]也是111 就是说data2和score共用一个地址,对这两个变量哪个操作都是对相同数组的操作
data3 = np.copy(score) # 深拷贝 =====>产生一个副本,data3和score两个变量指向两个不同的地址,互不影响
【参考:《走在小路上》】
【参考:解释的话语参考《书》P126】
- numpy.frombuffer(): 接受 buffer 输入参数,以流的形式读入转化成 ndarray 对象。
- numpy.fromiter():方法从可迭代对象中建立 ndarray 对象,返回一维数组。
【参考:《菜鸟教程》】
5、随机数组创建np.random.***:
- ※np.random.rand():
- rand函数根据给定维度生成默认**[0,1)之间生成均匀分布(uniform distribution)的随机数**。
- 里面的参数表示返回的ndarray形状
- 数组中的每个元素都是从0到1之间的均匀分布随机数。
import numpy as np
# 生成一个形状为[2, 3)的随机数数组
random_array = np.random.rand(2, 3)
print(random_array)
结果:
[[0.61215884 0.91686622 0.90061561]
[0.84619163 0.53418642 0.01144637]]
-
※np.random.randn():
-
方法用于生成标准正态分布(standard normal distribution)的随机数。
-
它返回一个由指定形状的随机数数组组成的
numpy.ndarray
对象。 -
数组中的每个元素都是从标准正态分布(均值为0,标准差为1)中生成的随机数。
-
示例:
import numpy as np
# 生成一个形状为(2, 3)的标准正态分布随机数数组
random_array = np.random.randn(2, 3)
【※总结:】
random.rand()
用于生成均匀分布的随机数,
random.randn()
用于生成标准正态分布的随机数。
这些函数在模拟和生成随机数据时非常有用,例如在统计分析、机器学习和数据科学领域中常常用到。
- **※numpy.random.seed():**当我们设置相同的seed,每次生成的随机数相同。如果不设置seed,则每次会生成不同的随机数,这在实验、测试和调试中非常有用,因为你可以确保结果的一致性。
import numpy as np
# 设置随机数生成器的种子为42
np.random.seed(42)
# 生成随机整数
random_int = np.random.randint(0, 10)
print("随机整数:", random_int)
# 生成随机浮点数数组
random_array = np.random.rand(3, 3)
print("随机浮点数数组:\n", random_array)
- ※np.random.uniform(low=-1, high=1, size=1000000)
生成均匀分布的一组数[low,high)
-
**enpty()函数 :**注意他生成的可不是默认元素值为0
-
**ones()函数 、ones_like()**函数等
-
**zeros()函数、zeros_like()**函数等
【注释:】具体见 书《利用Python进行数据分析第二版》 P120页
《菜鸟教程》
《走在小路上》
6、从数值范围创建数组
-
※numpy.arange(start, stop, step, dtype)
根据 start 与 stop 指定的范围以及 step 设定的步长,生成一个 ndarray。
示例:
import numpy as np
x = np.arange(10,20,2)
print (x)
结果:
[10 12 14 16 18]
-
※np.linspace(start, stop, num=50, endpoint=True, retstep=False, dtype=None)
创建一个等差数列
(官方解释:numpy.linspace 函数用于创建一个一维数组,数组是一个等差数列构成的,格式如下:)
参数 描述 start
序列的起始值 stop
序列的终止值,如果 endpoint
为true
,该值包含于数列中num
要生成的等步长的样本数量,默认为 50
endpoint
该值为 true
时,数列中包含stop
值,反之不包含,默认是True。retstep
如果为 True 时,生成的数组中会显示间距,反之不显示。 dtype
ndarray
的数据类型 示例:
import numpy as np a = np.linspace(1,10,10) print(a)
结果:
[ 1. 2. 3. 4. 5. 6. 7. 8. 9. 10.]
-
np.logspace(start, stop, num=50, endpoint=True, base=10.0, dtype=None)
创建一个于等比数列
参数 描述 start
序列的起始值为:base ** start stop
序列的终止值为:base ** stop。如果 endpoint
为true
,该值包含于数列中num
要生成的等步长的样本数量,默认为 50
endpoint
该值为 true
时,数列中中包含stop
值,反之不包含,默认是True。base
对数 log 的底数。 dtype
ndarray
的数据类型
示例:
a = np.logspace(1.0, 2.0, num = 10)
【参考:《菜鸟教程》】
7※、np.random.rand和np.ramdom.uniform()区别
np.random.rand
函数和 np.random.uniform
函数都是用于生成均匀分布的随机数的。
这两个函数的主要区别在于:
np.random.rand
函数生成的随机数在 [0,1) 的区间内均匀分布,即生成的随机数范围是左闭右开的。
np.random.uniform
函数生成的随机数的范围是可以自定义的。你可以使用参数 low
和 high
来指定生成的随机数的范围,并且这个范围是左闭右闭的。
- uniform()定义:
random_array = np.random.uniform(low=1,high=10,size=5)
print(random_array)
结果:
[4.84093034 9.17741176 4.13727806 3.54202278 3.68412662]
- rand()定义:
import numpy as np
# 生成一个形状为[2, 3)的随机数数组
random_array = np.random.rand(2, 3)
print(random_array)
8※、np.ramom.normal()和np.random.randn()区别
摘要:randn, normal这两个函数都可以返回随机正态分布的数组, 它们是从特殊到一般的形式。normal这个函数更加通用,且名字好记,建议平时使用这个函数生成正态分布。
-
np.random.normal
允许你生成具有自定义均值和标准差的正态分布随机数。 -
np.random.randn
用于生成标准正态分布随机数,无需指定均值和标准差。 -
如果你需要生成不同均值和标准差的正态分布随机数,可以使用
np.random.normal
,而如果只需要标准正态分布随机数,则可以使用np.random.randn
。 -
np.random.normal
函数:-
np.random.normal
是一个独立于np.random.randn
的函数,用于生成服从指定均值和标准差的正态分布随机数。 -
你需要提供两个参数:均值(
loc
)和标准差(scale
)。 -
这个函数可以生成不仅仅是标准正态分布(均值为0,标准差为1)的随机数,还可以生成其他均值和标准差的正态分布随机数。
-
import numpy as np
# 生成均值为2,标准差为3的正态分布随机数
random_numbers = np.random.normal(loc=2, scale=3, size=5)
-
np.random.randn
函数-
np.random.randn
是一个用于生成标准正态分布(均值为0,标准差为1)的随机数的特定函数。 -
不需要传递均值和标准差参数,只需要指定要生成的随机数的数量,它们将自动服从标准正态分布
-
import numpy as np
# 生成5个标准正态分布随机数
random_numbers = np.random.randn(5)
9、基本 的索引和切片
-
简单的索引:
-
方法一:8arr[0] 、 arr[5:8] 、 arr[:] 、 arr[2:]
b = a[2:7:2] # 从索引 2 开始到索引 7 停止,间隔为 2
注意:
比如: arr_slic = arr[5:8] 当我对 arr_slic[:] = 55555 修改其值的时候,arr[5:8]其实也变成了5555,这就是 ‘浅拷贝’, 就是说arr和arr_slic共用一个地址,对这两个变量哪个操作都是对相同数组的操作
由于NumPy 的设计⽬的是处理⼤数据,所以你可以想象⼀下,假如NumPy 坚持要将数据复制来复制去的话会产⽣何等的性能和内存问题。
【参考:《书》 P126】
- 方法二:
内置的 slice 函数,并设置 start, stop 及 step 参数进行,从原数组中切割出一个新数组。
s = slice(2,7,2) # 从索引 2 开始到索引 7 停止,间隔为2
【参考:《菜鸟教程》】
-
方法三:
切片还可以包括省略号 …,来使选择元组的长度与数组的维度相同。 如果在行位置使用省略号,它将返回包含行中元素的 ndarray。
import numpy as np a = np.array([[1,2,3],[3,4,5],[4,5,6]]) print (a[...,1]) # 第2列元素 print (a[1,...]) # 第2行元素 print (a[...,1:]) # 第2列及剩下的所有元素
【参考:《菜鸟教程》】
-
10、高级索引
- 布尔类型索引
In [99]: data = np.random.randn(7, 4)
In [100]: array(['Bob', 'Joe', 'Will', 'Bob', 'Will', 'Joe',]
In [114]: data
Out[114]:
array([[0.0929, 0.2817, 0.769 , 1.2464],
[ 1.0072, 0. , 0.275 , 0.2289],
[ 1.3529, 0.8864, 0. , 0. ],
[ 1.669 , 0. , 0. , 0.477 ],
[ 3.2489, 0. , 0. , 0.1241],
[ 0.3026, 0.5238, 0.0009 , 1.3438],
[ 0. , 0. , 0. , 0. ]])
选取这三个名字中的两个需要组合应⽤多个布尔条件,使⽤ **&(和)、|(或)**之类的布尔算术运算符即可:
In [101]: mask = (names == 'Bob') | (names == 'Will')
In [111]: mask
Out[111]: array([ True, False, True, True, True])
In [112]: data[mask]
输出的结果是: data[0] data[2] data[3] data[4] 里的数据
11、数组转置 和 轴对称
-
arr.T():数组转置
-
arr.swapaxes(1, 2):轴对称
4.2 通⽤函数:利⽤数组进⾏数据处理
NumPy数组使你可以将许多种数据处理任务表述为简洁的数组 表达式(否则需要编写循环)
⼀般来说,⽮量化数组运算要⽐等价的纯 Python⽅式快上⼀两个数量级
1、字符串函数
函数 | 描述 |
---|---|
add() | 对两个数组的逐个字符串元素进行连接 |
multiply() | 返回按元素多重连接后的字符串 |
center() | 居中字符串 |
capitalize() | 将字符串第一个字母转换为大写 |
title() | 将字符串的每个单词的第一个字母转换为大写 |
lower() | 数组元素转换为小写 |
upper() | 数组元素转换为大写 |
※split() | 指定分隔符对字符串进行分割,并返回数组列表 |
splitlines() | 返回元素中的行列表,以换行符分割 |
※strip() | 移除元素开头或者结尾处的特定字符 |
join() | 通过指定分隔符来连接数组中的元素 |
replace() | 使用新字符串替换字符串中的所有子字符串 |
decode() | 数组元素依次调用str.decode |
encode() | 数组元素依次调用str.encode |
【参考:《菜鸟教程》】
2、数学函数
1、NumPy 提供了标准的三角函数:
sin()、cos()、tan()。
2、numpy.around() :
函数返回指定数字的四舍五入值。
3、numpy.floor() :
返回小于或者等于指定表达式的最大整数,即向下取整。
4、numpy.ceil():
返回大于或者等于指定表达式的最小整数,即向上取整。
※5、numpy.isnan():
返回一个表示“那些值是NaN”或者“那些元素的无穷的”的bool数组
【!!注意哦:返回的是数组】
※6、exp:
返回个元素的指数e^x
※7、abs、fabs:
计算整数/浮点数 的绝对值
※8、less、less_equal、equal、not_qual:
相当于中缀运算符中的>、>=、<、<=、==、!=
【!!!注意哦:返回的是一个bool类型的数组】
※9、sqrt():
计算各个元素的平方
【参考:《菜鸟教程》】
3、算数函数
1、NumPy 算术函数包含简单的加减乘除:
add(),subtract(),multiply() 和 divide()。
需要注意的是数组必须具有相同的形状或符合数组广播规则。
2、numpy.reciprocal()
函数返回参数逐元素的倒数。如 1/4 倒数为 4/1。
3、numpy.power()
函数将第一个输入数组中的元素作为底数,计算它与第二个输入数组中相应元素的幂。
4、numpy.mod()
计算输入数组中相应元素的相除后的余数。 函数 numpy.remainder() 也产生相同的结果
5、sqrt和exp:
【参考:《菜鸟教程》】
4、※统计函数
1、※numpy.amin() 和 numpy.amax()
numpy.amin() 用于计算数组中的元素沿指定轴的最小值。
numpy.amax() 用于计算数组中的元素沿指定轴的最大值。
2、numpy.ptp()
函数计算数组中元素最大值与最小值的差(最大值 - 最小值)。
3、numpy.percentile()
百分位数是统计中使用的度量,表示小于这个值的观察值的百分比。 函数numpy.percentile()接受以下参数。
4、※numpy.median()
numpy.median() 函数用于计算数组 a 中元素的中位数(中值)
5、※numpy.mean()
numpy.mean() 函数返回数组中元素的算术平均值,如果提供了轴,则沿其计算。
6、※numpy.average()
numpy.average() 函数根据在另一个数组中给出的各自的权重计算数组中元素的加权平均值。
7、※numpty.std()
标准差函数(np.std([1,2,3,4]))
8、numpty.var()
标准差函数np.var([1,2,3,4])
※9、numpty.cumsum累加函数:
※10、numpty.prod累乘函数:
5、※排序、条件筛选函数
1、numpy.sort():
numpy.sort() 函数返回输入数组的排序副本。
【!!!注意哦,返回的是满足条件的元素】
2、numpy.argsort():
排序完成后返回的是对应数组的索引值
【!!!注意哦,返回的是满足条件的索引值】
※3、numpy.numpy.where()
numpy.where() 函数返回输入数组中满足给定条件的元素的索引。
【!!注意哦,返回的是满足条件的索引】
它会比纯Python中的三元表达式x if condition else y快上 1!~2个数量级,是他的矢量化版本
(同时,三元表达式还具备一下一些限制:第⼀,它对⼤数组的处理速度不是很快(因为所 有⼯作都是由纯Python完成的)。第⼆,⽆法⽤于多维数组。)
import numpy as np
x = np.arange(9.).reshape(3, 3)
print ('我们的数组是:')
print (x)
print ( '大于 3 的元素的索引:')
y = np.where(x > 3)
print (y)
print ('使用这些索引来获取满足条件的元素:')
print (x[y])
结果:
我们的数组是:
[[0. 1. 2.]
[3. 4. 5.]
[6. 7. 8.]]
大于 3 的元素的索引:
(array([1, 1, 2, 2, 2]), array([1, 2, 0, 1, 2]))
使用这些索引来获取满足条件的元素:
[4. 5. 6. 7. 8.]
※4、numpy.extract()
numpy.extract() 函数根据某个条件从数组中抽取元素,返回满条件的元素。
【!!!注意哦,返回的是满足条件的元素——————这就就是和Where的区别】
import numpy as np
x = np.arange(9.).reshape(3, 3)
print ('我们的数组是:')
print (x)
# 定义条件, 选择偶数元素
condition = np.mod(x,2) == 0
print ('按元素的条件值:')
print (condition)
print ('使用条件提取元素:')
print (np.extract(condition, x))
结果:
我们的数组是:
[[0. 1. 2.]
[3. 4. 5.]
[6. 7. 8.]]
按元素的条件值:
[[ True False True]
[False True False]
[ True False True]]
使用条件提取元素:
[0. 2. 4. 6. 8.]
※5、numpy.argmax() 和 numpy.argmin()
numpy.argmax() 和 numpy.argmin()函数分别沿给定轴返回最大和最小元素的索引。
import numpy as np
a = np.array([[30,40,70],[80,20,10],[50,90,60]])
print ('我们的数组是:')
print (a)
print ('\n')
print ('调用 argmax() 函数:')
print (np.argmax(a))
print ('\n')
print ('展开数组:')
print (a.flatten())
print ('\n')
print ('沿轴 0 的最大值索引:')
maxindex = np.argmax(a, axis = 0)
print (maxindex)
print ('\n')
print ('沿轴 1 的最大值索引:')
maxindex = np.argmax(a, axis = 1)
print (maxindex)
print ('\n')
print ('调用 argmin() 函数:')
minindex = np.argmin(a)
print (minindex)
print ('\n')
print ('展开数组中的最小值:')
print (a.flatten()[minindex])
print ('\n')
print ('沿轴 0 的最小值索引:')
minindex = np.argmin(a, axis = 0)
print (minindex)
print ('\n')
print ('沿轴 1 的最小值索引:')
minindex = np.argmin(a, axis = 1)
print (minindex)
结果:
我们的数组是:
[[30 40 70]
[80 20 10]
[50 90 60]]
调用 argmax() 函数:
7
展开数组:
[30 40 70 80 20 10 50 90 60]
沿轴 0 的最大值索引:
[1 2 0]
沿轴 1 的最大值索引:
[2 0 1]
调用 argmin() 函数:
5
展开数组中的最小值:
10
沿轴 0 的最小值索引:
[0 1 1]
沿轴 1 的最小值索引:
[0 2 0]
【!!!注意哦:返回的是满足条件的索引】
※6、另外还有两个⽅法any和all,
它们对布尔型数组⾮常有⽤。any⽤ 于测试数组中是否存在⼀个或多个True,⽽all则检查数组中所有 值是否都是True
In [192]: bools = np.array([False, False, True, False])
In [193]: bools.any()
Out[193]: True
In [194]: bools.all()
Out[194]: False
※7、np.unique(x):
去重函数,去除集合中重复的
※8、np.intersect1(x,y):
计算x和y中的公共元素,并返回有序结果
※9、np.union1d(x,y):
计算x和y的并集,并返回有序结果
※10、np.in1d(x,y):
计算x元素是否包含在y中
※11、np.setdiff1d(x,y):
计算集合的差,即:元素在x中不在y中
4.3 线性代数
NumPy 提供了线性代数函数库 linalg,该库包含了线性代数所需的所有功能,可以看看下面的说明:
函数 | 描述 |
---|---|
dot | 两个数组的点积,即元素对应相乘。 |
vdot | 两个向量的点积 |
inner | 两个数组的内积 |
matmul | 两个数组的矩阵积 |
determinant | 数组的行列式 |
solve | 求解 |
inv | 计算矩阵的乘法逆矩阵 |