Bootstrap

期末复习数据分析-NumPy的使用

NumPy

NumPy(Numerical Python的简称)是一个开源的Python库,用于科学计算和数据分析。它提供了强大的多维数组对象以及对这些数组的高级计算功能。NumPy是Python科学计算的基础库之一,很多其他的科学计算库(如Pandas、SciPy、Matplotlib等)都依赖于NumPy。

以下是NumPy的一些主要特点:

  1. 多维数组(ndarray):NumPy提供了一个强大的N维数组对象,它是NumPy的核心。这些数组比Python原生的列表类型更高效,因为它们在内存中是连续存储的,并且NumPy的数组支持大量的数学运算。

  2. 数组广播(Broadcasting):NumPy允许不同形状的数组之间进行运算,这在处理不同大小的数组时非常有用。

  3. 数学函数库:NumPy提供了大量的数学函数,如三角函数、算术运算、统计函数等,这些函数可以直接在数组上操作,而不需要编写循环。

  4. 线性代数:NumPy提供了线性代数运算的功能,包括矩阵乘法、行列式、特征值等。

  5. 随机数生成:NumPy包含了一套完整的随机数生成器,可以生成各种分布的随机数。

  6. 傅里叶变换:NumPy提供了傅里叶变换的功能,这对于信号处理等领域非常有用。

  7. 集成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函数创建数组

创建一维数组

import numpy as np

# 创建一维数组
arr1 = numpy.array([1,2,3,4,5])
print(arr1)
# 查看arr1的类型
print(type(arr1))

 

# 创建二维数组
data = [[1,2,3,4,5],[6,7,8,9,110]]
arr2 = np.array(data)
print(arr2)
print(arr2.ndim) # 查看是几维数组

 

 # 创建三维数组
 # 创建一个三维列表,每个子列表包含两个子列表,每个子列表包含三个整数
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创建数组
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数组
# ones()函数创建全1数组
arr2 = np.ones(10) #数组长度为10
print(arr2)
# ones函数创建10行3列全1数组
arr3 = np.ones((10,3)) # 传递一个元组
print(arr3)
arr3.shape

 

# ones函数创建5个 3行2列 全1数组
arr3 = np.ones((5,3,2)) # 传递一个元组
print(arr3)
arr3.shape

zeros()函数创建全0数组

zeros函数使用方法与ones相同,只不过一个全0,一个全1

# zeros()函数创建全0数组
arr4 = np.zeros((3,2)) # 创建3行2列全0数组
print(arr4)

empty()函数创建空数组
# empty()函数创建空数组
arr5 = np.empty((2,3,4))
print(arr5)

属性总览
 

 

# 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数据类型

 

 

# 查看数据类型
arr1 = np.ones(10)
print(arr1)
print(arr1.dtype)

arr2 = np.zeros(10)
print(arr2)
print(arr2.dtype)

# 设置数据类型
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)

 

# 类型转换 astype
arr = np.arange(10)
print(arr.dtype)
float_arr = arr.astype(np.float64)
print(float_arr.dtype)

 

3.索引

首先要认识维度,一维二维三维,这里的axis并不是坐标轴,而是一种方向

 我们一眼可以识别下面是一个三维数组,因为最外层有三个括号,

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
# 获取索引
print(arr3d[0][1][2])

输出结果:
6
# 索引赋值
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]]]
# 使用以下赋值方式是无法保存副本的
arr3 = arr3d
arr3d[1][1] = [11,12,13]
print(arr3d)
print(arr3)

# 应该使用 copy 副本
arr3 = arr3d.copy()
arr3d[1][1] = [10,11,12]
print(arr3d)
print(arr3)

 

4.切片

切片操作,维度不会发生变化;使用索引会降维

# 定义一个三维数组
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]]]

 

# 索引方式会降维
print(arr3d[:1])
# 获取三维中第二个,所有行,下标为1的内容
print(arr3d[:1,:,1])# 使用一次索引,降到二维

输出结果:

[[[1 2 3]
  [4 5 6]]]
[[2 5]]

布尔型索引是NumPy中一种强大的数据选择方法,它允许你使用布尔数组来选择数据的子集

【示例一】

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 位置对应的元素组成的一维数组。

# 输出结果
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]

【示例二】

# 布尔型索引
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]]
names == 'Andy'

输出结果:
array([ True, False, False, False])
data[np.array([ True, False, False, False])]

输出结果:
array([[-1.54862424,  2.52836987, -0.14063061, -1.09477535]])

5.数组的运算

# 数组数值运算
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]]
# 数组转置
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通用函数的关键点:

特点

  1. 逐元素操作:ufuncs对数组中的每个元素进行操作,类似于标量操作。

  2. 广播:ufuncs可以与不同形状的数组一起使用,并且能够自动进行广播。

  3. 类型转换: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执行元素级的真值逻辑
# 计算数组中每一个元素绝对值
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所有元素的累计积

 【使用示例】

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]]
# 计算方差和标准差
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

;