NumPy入个门吧

2024-02-24 09:03:38 浏览数 (2)

NumPy是什么?

NumPy 的全称叫 Numerical Python ,它是 Python 科学计算最重要的基础包之一。很多提供科学计算的包都是基于 NumPy 之上建立的,著名的 pandas 也是。

NumPy 核心的数据结构叫 ND array ,也就是多维数组。和 Python 里的列表有点相似,但又不一样。NumPy 的多维数组比 Python 的列表更高效,因为它底层是用C语言编写的。

NumPy 在数据分析领域是一个热门工具,它可以用于数据整理、清洗、过滤、排序、转换和计算。NumPy 的数据类型需要统一,所以在进行大规模数学运算时它的执行效率会非常高。在做数据分析时,通常会对数值型和布尔型数据进行操作。如果数组中既有文本又有数字就不能进行算数运算了,而且NumPy 也会将整个数组的数据类型变成 object

学习 NumPy 最重要掌握向量化、广播和通用函数。这些内容本文都会讲到。

安装并使用NumPy

安装 NumPy

使用以下命令安装 NumPy

代码语言:javascript复制
pip install numpy

引入 NumPy

在使用 NumPy 之前,要先引入它。

代码语言:javascript复制
import numpy as np

创建数组

手动传值

NumPy 的核心数据结构是多维数组,要创建数组可以用 array 方法。

array 函数能接收任意序列型的对象,然后生成一个包含传入数据的 NumPy 数组。

代码语言:javascript复制
# 一维数组
arr = np.array([1, 2, 3])

# 二维数组
arr = np.array([[1, 2, 3],
                [4, 5, 6]])

多少维数组,数左边的方括号数量就知道了。

你也可以这么写。

代码语言:javascript复制
data = [1, 2, 3]
arr = np.array(data)

除了上面这种手动传入值的方法,还可以用 NumPy 提供的方法创建特殊数组。

zeros: 全0数组

创建元素全为0的数组,可以用 zeros 方法

代码语言:javascript复制
arr = np.zeros(6)
print(arr) # 输出:array([0., 0., 0., 0., 0., 0.])

如果你需要创建多维数组,且值全为0,可以这么做:

代码语言:javascript复制
np.zeros((行数, 列数))

需要注意,此时 zeros 后面跟着2层括号。

代码语言:javascript复制
arr = np.zeros((3, 4))
print(arr)

```
输出:
array([[0., 0., 0., 0.],
       [0., 0., 0., 0.],
       [0., 0., 0., 0.]])
```

ones: 全1数组

创建元素全为1的数组,可以用 ones 方法

代码语言:javascript复制
arr = np.ones(6)
print(arr) # 输出:array([1., 1., 1., 1., 1., 1.])

要使用 ones 创建多维数组,且值全为1,和 zeros 创建多维数组的语法是一样的。

代码语言:javascript复制
np.ones((行数, 列数))

需要注意,在使用 zerosones 方法创建数组时,所有元素都是有小数点的,创建出来的元素都是浮点数。

empty: 空值数组

创建空值数组,可以使用 empty 方法

语法如下:

代码语言:javascript复制
# 一维
np.empty(元素个数)

# 多维
np.empyt((行数, 列数))

arange: 范围数组

arangeNumPy 提供的一种快速创建数组的方法,它和 Pythonrange 有点像。

语法如下:

代码语言:javascript复制
np.arange(起始值, 结束值, 步长)

举个例子,创建一个0~10,步长为2的数组。

代码语言:javascript复制
arr = np.arange(0, 10, 2)
print(arr) # 输出:array([0, 2, 4, 6, 8])

arange 创建的数组是不包含结束值的。

如果你只传1个值也行,那数组的值会从0开始,到你指定的值结束(不包含指定值)。比如:

代码语言:javascript复制
arr = np.arange(10)
print(arr) # 输出:array([0, 1, 2, 3, 4, 5, 6, 7, 8, 9])

随机数多维数组

使用 np.random.randn(行数, 列数) 可以创建一个指定行数和列数,元素值为随机数的数组。

比如生成一个2行3列,值为随机数的数组。

代码语言:javascript复制
arr = np.random.randn(2, 3)
print(arr)

```
输出:
array([[-1.40881835,  0.13351722, -1.46305705],
       [-0.1046862 ,  0.63644499,  0.4796577 ]])
```

访问数组元素

数字索引

访问 NumPy 数组元素的方法和 Python 访问列表元素的方法一样,都是使用“方括号”和“下标”进行访问。下标从0开始。

代码语言:javascript复制
arr = np.array([1, 2, 3])
print(arr[1]) # 输出:2

如果要访问二维数组的某个元素,可以这样写:

代码语言:javascript复制
arr = np.array([[10, 2, 3, 40],
               [50, 60, 7, 8]])
print(arr[0][3]) # 输出:40

访问多维数组也是同样原理。

NumPy 也支持切片的方式访问,切片需要传入一个起始索引(包含自身)和一个结束索引(不包含自身),两个索引之间用一个冒号分隔。

代码语言:javascript复制
arr = np.array([1, 2, 3, 4, 5, 6, 7, 8, 9])
print(arr[1:4]) # 输出:[2 3 4]

多维数组的切片方法:

代码语言:javascript复制
arr = np.array([[10, 2, 3, 40],
               [50, 60, 7, 8]])
print(arr[1:2, 1:2]) # 输出:60

既然能获取,那就能修改。

代码语言:javascript复制
arr = np.array([1, 2, 3, 4])
arr[0] = 100
print(arr) # 输出:[100   2   3   4]

通过切片的方式获取到的元素,修改值时也会影响原数组的值。

布尔型索引

NumPy 的数组还支持布尔型索引。

代码语言:javascript复制
arr1 = np.array([1, 2, 3, 4, 5])
arr2 = np.array([True, False, True, False, False])
print(arr1[arr2]) # 输出:[1 3]

布尔型索引的相关应用稍后会讲到。

向量化和广播

向量化和广播都是在解决“遍历”问题。

比如你需要让数组的每个元素值增加1,你可以直接用数组 1,不需要手动一个个元素进行遍历。这叫向量化

NumPy 会将标量值传播到数组的各个元素。标量指的是一种数据类型,比如浮点型和字符串。

代码语言:javascript复制
arr = np.array([[1, 2, 3, 4],
               [5, 6, 7, 8]])
print(arr   1)

```
输出:
[[2 3 4 5]
 [6 7 8 9]]
```

在处理两个形状相同的数组也是同样道理。

代码语言:javascript复制
arr1 = np.array([[1, 2, 3, 4],
               [5, 6, 7, 8]])
arr2 = np.array([[10, 20, 30, 40],
               [50, 60, 70, 80]])
print(arr1   arr2)

```
输出:
[[11 22 33 44]
 [55 66 77 88]]
```

如果大小相同的数组做比较的话,会生成一个布尔值数组。

代码语言:javascript复制
arr1 = np.array([[1, 20, 30, 4],
               [5, 6, 70, 80]])
arr2 = np.array([[10, 2, 3, 40],
               [50, 60, 7, 8]])
print(arr1 > arr2)

```
输出:
[[False  True  True False]
 [False False  True  True]]
```

如果两个数组的形状不一样,NumPy 会自动将较小的数组扩展成较大数组的形状,这叫广播

代码语言:javascript复制
arr1 = np.array([10, 20, 30, 40])
arr2 = np.array([[10, 2, 3, 40],
               [50, 60, 7, 8]])
print(arr1   arr2)

```
输出:
[[20 22 33 80]
 [60 80 37 48]]
```

常用方法

接下来会讲一些 NumPy 的常用方法,包含大家说的“通用函数”。

ndim: 获取数组维度

前面提到可以通过数方括号的方式知道数组的维度,除此之外,NumPy 也提供了一个 ndim 属性可以获取数组维度。

代码语言:javascript复制
arr1 = np.array([1, 2, 3])
arr2 = np.array([[1, 2, 3], [4, 5, 6]])

print(arr1.ndim) # 输出:1
print(arr2.ndim) # 输出:2

shape: 获取各个维度的元素的个数

使用 shape 可以获取数组各个维度的元素个数,并以元组的方式放回。

代码语言:javascript复制
arr1 = np.array([1, 2, 3])
arr2 = np.array([[1, 2, 3], [4, 5, 6]])

print(arr1.shape) # 输出:(3,)。只有1个数值,表示arr1只有1个维度,第1维度有3个元素。
print(arr2.shape) # 输出:(2, 3)。有2个数值,表示arr2有2个维度,第一个维度有2个元素,第2个维度有3个元素。

size: 获取数组元素的总数

只要不是九漏鱼应该都知道 size 这个单词的意思。

代码语言:javascript复制
arr1 = np.array([1, 2, 3])
arr2 = np.array([[1, 2, 3], [4, 5, 6]])

print(arr1.size) # 输出:3
print(arr2.size) # 输出:6

dtype: 返回数组元素的类型

使用 dtype 可以获取数组元素的数据类型。

代码语言:javascript复制
arr1 = np.array([1., 2., 3.])
arr2 = np.array([[1, 2, 3], [4, 5, 6]])
arr3 = np.array([True, False])

print(arr1.dtype) # 输出:float64
print(arr2.dtype) # 输出:int32
print(arr3.dtype) # 输出:bool

max(): 求最大值

使用 max() 方法可以求出数组元素的最大值,多维数组也可以。

代码语言:javascript复制
arr1 = np.array([1., 2., 3.])
arr2 = np.array([[10, 20, 30], [4, 5, 6]])

print(arr1.max()) # 输出:3.0
print(arr2.max()) # 输出:30

min(): 求最小值

代码语言:javascript复制
arr1 = np.array([1., 2., 3.])
arr2 = np.array([[10, 20, 30], [4, 5, 6]])

print(arr1.min()) # 输出:1.0
print(arr2.min()) # 输出:4

mean(): 求平均值

代码语言:javascript复制
arr1 = np.array([1., 2., 3.])
arr2 = np.array([[10, 20, 30], [4, 5, 6]])

print(arr1.mean()) # 输出:2.0
print(arr2.mean()) # 输出:12.5

sum(): 求和

代码语言:javascript复制
arr1 = np.array([1., 2., 3.])
arr2 = np.array([[10, 20, 30], [4, 5, 6]])

print(arr1.sum()) # 输出:6.0
print(arr2.sum()) # 输出:75

sort(): 排序

代码语言:javascript复制

NumPy 提供了一个排序方法,用的时候需要 np.sort(数组) 这样用。

代码语言:javascript复制
arr = np.array([10, 4, 2, 11, 3])
print(np.sort(arr)) # 输出:[ 2  3  4 10 11]
print(arr) # 输出:[10  4  2 11  3]

sorted(): 排序,Python内置方法

使用 sorted() 方法可以对数组进行排序,而且不会改变原数组。sorted()Python 内置的排序方法。

代码语言:javascript复制
arr = np.array([10, 4, 2, 11, 3])
print(sorted(arr)) # 输出:[2, 3, 4, 10, 11]
print(arr) # 输出: [10  4  2 11  3]

sorted() 方法第一个参数接收一个数组,默认是从小到大排序。

如果想从大到小排序,可以将 reverse 参数设置为 True

代码语言:javascript复制
arr = np.array([10, 4, 2, 11, 3])
print(sorted(arr, reverse=True)) # 输出:[11, 10, 4, 3, 2]

条件筛选

假如需要返回大于10的元素,可以这样写。

代码语言:javascript复制
arr = np.array([10, 40, 2, 11, 3])
print(arr > 10) # 输出:[False  True False  True False]

此时会返回一个布尔类型的数组,我们再将这个数组用前面提到的“布尔型索引”方法就能获取到大于10的元素了。

代码语言:javascript复制
arr = np.array([10, 40, 2, 11, 3])
print(arr[arr > 10]) # 输出:[40 11]

如果有多个筛选条件,我们需要使用 &(与)|(或),不能用 Python 关键字 andor

比如我们要筛选出大于10且小于20的值,可以这样写:

代码语言:javascript复制
arr = np.array([10, 40, 2, 11, 3])
print(arr[(arr > 10) & (arr < 20)]) # 输出:[11]

T: 轴对换

如果我们想将一个2行3列的数组变成3行2列,可以这样写:

代码语言:javascript复制
arr = np.array([[10, 20, 30],
              [303, 202, 101]])
arr.T

```
返回:
array([[ 10, 303],
       [ 20, 202],
       [ 30, 101]])
```

0 人点赞