NumPy
NumPy(Numerical Python的简称)是一个开源的Python库,用于科学计算和数据分析。它提供了强大的多维数组对象以及对这些数组的高级计算功能。NumPy是Python科学计算的基础库之一,很多其他的科学计算库(如Pandas、SciPy、Matplotlib等)都依赖于NumPy。
以下是NumPy的一些主要特点:
-
多维数组(ndarray):NumPy提供了一个强大的N维数组对象,它是NumPy的核心。这些数组比Python原生的列表类型更高效,因为它们在内存中是连续存储的,并且NumPy的数组支持大量的数学运算。
-
数组广播(Broadcasting):NumPy允许不同形状的数组之间进行运算,这在处理不同大小的数组时非常有用。
-
数学函数库:NumPy提供了大量的数学函数,如三角函数、算术运算、统计函数等,这些函数可以直接在数组上操作,而不需要编写循环。
-
线性代数:NumPy提供了线性代数运算的功能,包括矩阵乘法、行列式、特征值等。
-
随机数生成:NumPy包含了一套完整的随机数生成器,可以生成各种分布的随机数。
-
傅里叶变换:NumPy提供了傅里叶变换的功能,这对于信号处理等领域非常有用。
-
集成C/C++和Fortran代码:NumPy可以与C/C++和Fortran代码集成,这使得可以利用这些语言的高性能来加速计算。
NumPy因其高效性和易用性,在科学计算和数据分析领域得到了广泛应用。它使得Python成为了一个强大的科学计算环境,尤其是在数据科学、机器学习、图像处理等领域。
- 为什么python中有了列表,我们还是用numpy
numpy中的数组更快
-
内存分配:对于列表来说,它是一个可变类型数据,所以在分配内存的时候,就需要为它多分配一些额外的内存;而numpy中的数组长度是固定的,在分配内存的时候,就会为它分配一个固定长度的内存,所以说numpy占用的内存更小
-
列表中其实是存在指针的,在python中虽然隐去了指针的概念,但是列表是有指针的,比如下面的列表在内存中存储是这样的,我们是通过指针,来指向对应的值,这样我们在存储的时候就需要即存储指针,又需要存储这个整数的对象,这样就浪费了内存和计算时间
-
列表中的元素在系统中是分散存储的,而numpy中的数组是连续存储的,这样数组在遍历所有元素的时候又不需要像列表那样,对内存地址进行查找,从而节省了内存资源
1.创建n维数组
函数名 | 描述 | 示例代码 |
---|---|---|
array() | 从已有的数据(如列表、元组等)创建一个NumPy数组。 | np.array([1, 2, 3]) |
arange() | 创建一个包含给定范围内等差序列的数组。 | np.arange(0, 10, 2) |
ones() | 创建一个给定形状和数据类型的新数组,并填充为1。 | np.ones((2, 3)) |
ones_like() | 创建一个与给定数组形状和数据类型相同的数组,并填充为1。 | np.ones_like(np.array([[0, 0], [0, 0]])) |
zeros() | 创建一个给定形状和数据类型的新数组,并填充为0。 | np.zeros((2, 3)) |
zeros_like() | 创建一个与给定数组形状和数据类型相同的数组,并填充为0。 | np.zeros_like(np.array([[1, 1], [1, 1]])) |
empty() | 创建一个给定形状和数据类型的新数组,但不初始化其元素(内容是随机的,取决于内存状态)。 | np.empty((2, 3)) |
empty_like() | 创建一个与给定数组形状和数据类型相同的数组,但不初始化其元素。 | np.empty_like(np.array([[1, 1], [1, 1]])) |
eye() | 创建一个单位矩阵,对角线元素为1,其余元素为0。 | np.eye(3) |
identity() | 创建一个单位矩阵,与eye()函数相同,但仅限于2维。 | np.identity(3) |
使用array函数创建数组
创建一维数组
python
import numpy as np
# 创建一维数组
arr1 = numpy.array([1,2,3,4,5])
print(arr1)
# 查看arr1的类型
print(type(arr1))
python
# 创建二维数组
data = [[1,2,3,4,5],[6,7,8,9,110]]
arr2 = np.array(data)
print(arr2)
print(arr2.ndim) # 查看是几维数组
python
# 创建三维数组
# 创建一个三维列表,每个子列表包含两个子列表,每个子列表包含三个整数
data = [[[1,2,3],[4,5,6],[7,8,9]],[[6,7,8],[9,10,11],[12,13,14]]]
arr3 = np.array(data)
print(arr3)
print(type(arr3))
# 打印数组的形状,形状是一个元组,表示每个维度的大小
print(arr3.shape)
输出解释:
-
第一行打印的是三维数组的内容。
-
第二行显示数组的类型是
numpy.ndarray
。 -
第三行显示数组的形状是
(2, 3, 3)
,这意味着数组有2个二维数组,每个二维数组有3行3列。
使用arange创建数组
python
import numpy as np
# 用arange创建一维数组
arr1 = np.arange(10)
print(arr1)
print(type(arr1))
print("-------------")
arr2 = np.arange(1,10)
print(arr2)
print(type(arr2))
使用ones函数创建全1数组
python
# ones()函数创建全1数组
arr2 = np.ones(10) #数组长度为10
print(arr2)
python
# ones函数创建10行3列全1数组
arr3 = np.ones((10,3)) # 传递一个元组
print(arr3)
arr3.shape
python
# ones函数创建5个 3行2列 全1数组
arr3 = np.ones((5,3,2)) # 传递一个元组
print(arr3)
arr3.shape
zeros()函数创建全0数组
zeros函数使用方法与ones相同,只不过一个全0,一个全1
python
# zeros()函数创建全0数组
arr4 = np.zeros((3,2)) # 创建3行2列全0数组
print(arr4)
empty()函数创建空数组
python
# empty()函数创建空数组
arr5 = np.empty((2,3,4))
print(arr5)
属性总览
python
# empty()函数创建空数组
arr5 = np.empty((2, 3, 4))
print(arr5)
print(arr5.ndim)
print(arr5.shape)
print(arr5.dtype)
print(arr5.itemsize)
print(arr5.size)
print(arr5.nbytes)
2.ndarray数据类型
python
# 查看数据类型
arr1 = np.ones(10)
print(arr1)
print(arr1.dtype)
arr2 = np.zeros(10)
print(arr2)
print(arr2.dtype)
python
# 设置数据类型
arr = np.array([1,2,3,4,5])
print("arr原数组类型")
print(arr.dtype);
print("arr 强制类型转换")
arr = np.array([1,2,3,4,5],dtype=np.float64)
print(arr.dtype)
python
# 类型转换 astype
arr = np.arange(10)
print(arr.dtype)
float_arr = arr.astype(np.float64)
print(float_arr.dtype)
3.索引
首先要认识维度,一维二维三维,这里的axis并不是坐标轴,而是一种方向
我们一眼可以识别下面是一个三维数组,因为最外层有三个括号,
python
import numpy as np
# 创建一个3维数组,维度为3
arr3d = np.array([[[1,2,3],[4,5,6]],[[7,8,9],[11,12,13]]])
print(arr3d)
print(arr3d.ndim)
输出结果:
[[[ 1 2 3]
[ 4 5 6]]
[[ 7 8 9]
[11 12 13]]]
3
python
# 获取索引
print(arr3d[0][1][2])
输出结果:
6
python
# 索引赋值
print(arr3d[1][1])
# 将原来11 12 13 改为 10 11 12
arr3d[1][1] = [10,11,12]
print(arr3d)
输出结果:
[11 12 13]
[[[ 1 2 3]
[ 4 5 6]]
[[ 7 8 9]
[10 11 12]]]
python
# 使用以下赋值方式是无法保存副本的
arr3 = arr3d
arr3d[1][1] = [11,12,13]
print(arr3d)
print(arr3)
python
# 应该使用 copy 副本
arr3 = arr3d.copy()
arr3d[1][1] = [10,11,12]
print(arr3d)
print(arr3)
4.切片
切片操作,维度不会发生变化;使用索引会降维
python
# 定义一个三维数组
arr3d = np.array([[[1,2,3],[4,5,6]],[[7,8,9],[11,12,13]]])
print(arr3d)
输出结果:
[[[ 1 2 3]
[ 4 5 6]]
[[ 7 8 9]
[11 12 13]]]
# 获取三维中第二个内容
print(arr3d[1:])
输出结果:
[[[ 7 8 9]
[11 12 13]]]
# 获取三维中第二个,第二行内容
print(arr3d[1:,1:])
输出结果
[[[11 12 13]]]
# 获取三维中第二个,第二行,下标为3的内容
print(arr3d[1:,1:,2:]) #记得是2: 而不是2,2是索引会发生降维
输出结果:
[[[13]]]
python
# 索引方式会降维
print(arr3d[:1])
# 获取三维中第二个,所有行,下标为1的内容
print(arr3d[:1,:,1])# 使用一次索引,降到二维
输出结果:
[[[1 2 3]
[4 5 6]]]
[[2 5]]
布尔型索引是NumPy中一种强大的数据选择方法,它允许你使用布尔数组来选择数据的子集
【示例一】
python
import numpy as np
# 创建一个示例数组
arr = np.array([[1, 2, 3], [4, 5, 6], [7, 8, 9], [10, 11, 12]])
# 打印原始数组
print("Original array:")
print(arr)
# 创建一个布尔数组,表示哪些行应该被选择
# 在这个例子中,我们选择所有大于5的元素
bool_idx = arr > 5
# 打印布尔索引数组
print("\nBoolean index array:")
print(bool_idx)
# 使用布尔索引选择数组中大于5的元素
selected_elements = arr[bool_idx]
# 打印选择的元素
print("\nSelected elements:")
print(selected_elements)
在这个例子中,bool_idx
是一个布尔数组,它的形状与原始数组 arr
相同,其中 True
表示原始数组中相应位置的元素满足条件(例如,大于5),而 False
表示不满足条件。
当你使用布尔索引 arr[bool_idx]
时,NumPy 会返回一个由原始数组中所有 True
位置对应的元素组成的一维数组。
python
# 输出结果
Original array:
[[ 1 2 3]
[ 4 5 6]
[ 7 8 9]
[10 11 12]]
Boolean index array:
[[False False False]
[False False True]
[ True True True]
[ True True True]]
Selected elements:
[ 6 7 8 9 10 11 12]
【示例二】
python
# 布尔型索引
names = np.array(['Andy','Bill','Jack','Jame'])
print(names.ndim)
data = np.random.randn(4,4)
print(names)
print(data)
输出结果:
1
['Andy' 'Bill' 'Jack' 'Jame']
[[-1.54862424 2.52836987 -0.14063061 -1.09477535]
[ 0.09204507 0.64274378 0.46467384 -0.69950747]
[-0.7728008 0.065998 -0.62236696 0.95792246]
[ 1.45441249 0.71329319 0.85592692 -0.84604386]]
python
names == 'Andy'
输出结果:
array([ True, False, False, False])
python
data[np.array([ True, False, False, False])]
输出结果:
array([[-1.54862424, 2.52836987, -0.14063061, -1.09477535]])
5.数组的运算
python
# 数组数值运算
arr2d = np.array([[1,2,3],[4,5,6]])
print(arr2d)
print(arr2d * 2) #对数组每一个元素*2
print(arr2d * arr2d) # 数组乘数组,也就是每个元素的2次方
输出结果:
[[1 2 3]
[4 5 6]]
[[ 2 4 6]
[ 8 10 12]]
[[ 1 4 9]
[16 25 36]]
python
# 数组转置
arr = np.arange(15).reshape(5,3) # 重塑成5行3列
print(arr)
print(arr.T) # 行列互换
# x的转置点乘x
np.dot(arr.T,arr)
输出结果:
array([[270, 300, 330],
[300, 335, 370],
[330, 370, 410]])
6.通用函数
在NumPy中,通用函数(Universal Functions,简称ufunc)是一种对数组进行逐元素操作的函数。它们是NumPy的核心特性之一,允许你在数组上执行快速元素级计算。以下是一些关于NumPy通用函数的关键点:
特点
-
逐元素操作:ufuncs对数组中的每个元素进行操作,类似于标量操作。
-
广播:ufuncs可以与不同形状的数组一起使用,并且能够自动进行广播。
-
类型转换:ufuncs可以处理不同数据类型的数组,并在必要时进行类型转换。
通用函数分为一元函数和二元函数
一元函数(传递一个参数)
函数 | 说明 |
---|---|
abs、fabs | 计算整数、浮点数或复数的绝对值。对应非复数,可以使用更快的fabs |
sqrt | 计算各元素平方根,相当于array ** 0.5 |
square | 计算各元素平方,相当于array ** 2 |
exp | 计算各元素的指数 |
log、log10、log2、loglp | 分别以自然对数(底数e)、10、2、(1+x)的对数 |
sign | 计算各元素的正负号:1(正数)、0(零)、-1(负数) |
ceil | 计算各元素的ceiling值,即大于等于该值的最小整数 |
floor | 计算各元素的floor值,即小于等于该值的最大正数 |
rint | 将各元素值四舍五入到最接近的整数,保留dtype |
modf | 将数组的小数和整数部分以两个独立数组的形式返回 |
isnan | 返回一个表示"哪些是NAN"的布尔型数组 |
isfinite、isinf | 返回一个表示"哪些是finite、inf"的布尔型数组 |
cos、cosh、sin、sinh、tan、tanh | 普通型和双曲线三角函数 |
arccos、arccosh、arcsin、arcsinh、arctan、arctanh | 反三角函数 |
logical_not | 计算各元素not x的真值,相当于~arr |
二元函数(传递两个参数)
函数 | 说明 |
---|---|
add | 将数组中对应的元素相加 |
subtract | 从第一个数组中的元素减去第二个数组中的元素 |
multiply | 数组元素相乘 |
divide、floor_divide | 除法、向下圆整除法(丢弃余数) |
power | 对第一个数组中元素A,根据第二个数组中的相应位置元素B,计算A^B |
maximum、fmax | 元素级的最大值计算,fmax将忽略NaN |
minimum、fmin | 元素级的最小值计算,fmin将忽略NaN |
mod | 元素级的求模计算,(除法的余数) |
greater、greater_equal、less、less_equal、equal、not_equal | 执行元素级的比较运算,最终产生布尔型数组。相当于中级运算符>、>=、<、<=、==、!= |
logical_and、logical_or、logical_xor | 执行元素级的真值逻辑 |
python
# 计算数组中每一个元素绝对值
arr1 = np.array([-1,-2,-3,1,2,3])
np.abs(arr)
# 两个数组元素相加
arr2 = np.array([1,2,3,4,5,6])
np.add(arr1,arr2)
# 数组中每个元素向上取整
arr3 = np.array([1.2,.8,1.3,5.6])
np.ceil(arr3)
7.数据和统计方法
方法 | 描述 |
---|---|
sum | 对数组的所有或一个轴向上的元素求和。零长度的数组的和为灵。 |
mean | 算术平均值。灵长度的数组的均值为NaN。 |
std, var | 标准差和方差,有可选的调整自由度(默认值为n)。 |
min, max | 最大值和最小值 |
argmin, argmax | 索引最小和最大元素。 |
cumsum | 所有元素的累计和 |
cumprod | 所有元素的累计积 |
【使用示例】
python
arr = np.arange(15).reshape(5,3)
print(arr)
# 计算累计和
print(np.cumsum(arr))
# 计算1轴方向的累计积
print(np.cumprod(arr,axis=1))
输出结果:
[[ 0 1 2]
[ 3 4 5]
[ 6 7 8]
[ 9 10 11]
[12 13 14]]
[ 0 1 3 6 10 15 21 28 36 45 55 66 78 91 105]
[[ 0 0 0]
[ 3 12 60]
[ 6 42 336]
[ 9 90 990]
[ 12 156 2184]]
python
# 计算方差和标准差
arr = np.random.randn(5,4)
print(arr)
print(np.std(arr))
print(np.var(arr))
输出结果
[[-0.82702667 0.53004555 -0.88615354 0.45744669]
[-0.2719961 -0.66280686 0.26270074 0.53249467]
[-1.47459869 0.27185212 0.30708845 -1.42677151]
[ 0.08378782 -0.48001723 1.72088513 -0.67995086]
[ 0.97809438 1.36821827 -0.66781934 -0.57002813]]
0.8473945971142745
0.7180776032184635