NumPy 概述

NumPy 是 Python 中做科学计算的基础库,也是大部分 Python 科学计算库的基础库。主要用于:

  • 数值计算
  • 大型多维数组(矩阵)的操作和处理

常用方法

创建数组

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
list_1 = [1, 2, 3, 4, 5]
list_2 = [6, 7, 8, 9, 10]

# 创建一维数组(方法一)
a = np.array(list_1)

# 创建一维数组(方法二):起始、终止、步长
b = np.arange(1, 10, 2)

# 创建二维数组
c = np.array([list_1, list_2])

# 创建全0一维数组(数据类型是float64)
d = np.zeros(5)

# 创建全0二维数组(数据类型是float64)
e = np.zeros([2, 3])

# 创建单位矩阵(数据类型是float64)
f = np.eye(5)

# 通过reshape创建数组
np.arange(12).reshape(3, 4)

数组的属性

1
2
3
4
5
6
7
8
9
10
11
# 查看数组的类型
type(a)

# 查看数据的类型
a.dtype

# 查看数组的形状
a.shape

# 查看数组的元素个数
a.size

数组的访问

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
# 一维数组
a = np.arange(1, 10) # out: array([1, 2, 3, 4, 5, 6, 7, 8, 9])
a[1] # out: 2
a[1:5] # out: array([2, 3, 4, 5])

# 二维数组
b = np.array([[1, 2, 3],
[4, 5, 6]]) # [1,2,3]是第0行,[4,5,6]是第1行

b[1][0] # out: 4,访问方式一
b[1, 0] # out: 4,访问方式二

c = np.array([[1, 2, 3],
[4, 5, 6],
[7, 8, 9]])

c[:2, 1:] # 前2行,第1列开始
# out:
# array([[2, 3],
# [5, 6]])

指定创建数组的数据类型

1
2
3
4
a = np.array([1, 0, 1, 0], dtype=np.bool_)  # 或者使用 dtype='?'

# 修改数组的数据类型
a.astype("i1") # 或者使用 a.astype(np.int8)

修改浮点型的小数位数

1
np.round(b, 2)  # b是浮点型数组

数组的形状

1
2
3
4
5
6
7
8
9
10
11
12
# 查看数组的形状,得到的结果是一个元组
a.shape # 例如 (2, 4) 表示 2行 * 4列 的数组

# 获取数组的行数和列数
a.shape[0] # 行数
a.shape[1] # 列数

# 修改数组的形状
b = a.reshape(2, 6)

# 把数组转化为一维数组
a.flatten()

数组和数组的计算(广播机制)

1
2
a + 1
a * 3

广播规则:如果两个数组的后缘维度(即从末尾开始算起的维度)的轴长度相符或其中一方的长度为1,则认为它们是广播兼容的。广播会在缺失和(或)长度为1的维度上进行。

简单来说,两个数组 shape 得到的元组的后2位要相同,或者后2位中一个相同,另外一个数字有一个数组为1。

NumPy 读取数据

1
2
3
4
np.loadtxt(fname, dtype=np.float, delimiter=None, skiprows=0, usecols=None, unpack=False)

# 示例
np.loadtxt(US_video_data_numbers_path, delimiter=",", dtype=int, unpack=1)
参数 解释
frame 文件、字符串或产生器,可以是 .gz 或 .bz2 压缩文件
dtype 数据类型,csv 的字符串以什么数据类型读入数组中,默认 np.float
delimiter 分割字符串,默认是任何空格,改为逗号
skiprows 跳过前 X 行,一般跳过第一行表头
usecols 读取指定的列,索引,元组类型
unpack 如果 True,读入属性将分别写入不同数组变量,False 读入数据只写入一个数组变量,默认 False,相当于转置的效果

NumPy 中的转置

转置是一种变换,对于 NumPy 中的数组来说,就是在对角线方向交换数据,目的是为了更方便地处理数据。

1
2
3
4
# 转置的3种方法
t.transpose()
t.swapaxes(1, 0)
t.T

NumPy 的索引和切片

1
2
3
4
5
6
7
8
a[1]          # 取第2行
a[1:3] # 取第2到第3行
a[:, 2] # 取第3列
a[:, 2:4] # 取第3到第4列
a[[1, 3], :] # 分别取第2行和第3行
a[:, [2, 4]] # 分别取第3列和第4列
a[:, 2:8:2] # 取第3列到第8列,步长为2
a[:, 2:4] = 0 # 把第3列到第4列的值设置为0

NumPy 中布尔索引

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
t = np.arange(24).reshape(4, 6)

# 返回布尔数组
print(t < 10)
# out:
# array([[ True, True, True, True, True, True],
# [ True, True, True, True, False, False],
# [False, False, False, False, False, False],
# [False, False, False, False, False, False]])

# 布尔索引赋值
t[t < 10] = 0
print(t)
# out:
# [[ 0 0 0 0 0 0]
# [ 0 0 0 0 10 11]
# [12 13 14 15 16 17]
# [18 19 20 21 22 23]]

NumPy 中的三元运算符

把 t 中小于10的数字替换为0,大于10的替换为10:

1
2
3
4
5
6
7
t = np.where(t < 10, 0, 10)
print(t)
# out:
# [[ 0 0 0 0 0 0]
# [ 0 0 0 0 10 10]
# [10 10 10 10 10 10]
# [10 10 10 10 10 10]]

NumPy 中的 clip(裁剪)

把 t 中小于10的数字替换为0,大于20的数字替换为20,其他数字不变:

1
2
3
4
5
6
7
t = t.clip(10, 20)
print(t)
# out:
# [[10 10 10 10 10 10]
# [10 10 10 10 10 11]
# [12 13 14 15 16 17]
# [18 19 20 20 20 20]]

NumPy 中的 nan 和 inf

nan (NAN, Nan):not a number,表示不是一个数字。

什么时候会出现 nan:

  • 当我们读取本地的文件为 float 的时候,如果有缺失,就会出现 nan
  • 当做了一个不合适的计算的时候(比如无穷大减去无穷大)

inf (-inf, inf):infinity,inf 表示正无穷,-inf 表示负无穷。

什么时候会出现 inf:

  • 比如一个数字除以0(Python 中直接会报错,NumPy 中是一个 inf 或 -inf)

inf 和 nan 的 type 类型都是 float

nan 的注意点:

  • 两个 nan 是不相等的,即 np.nan != np.nan
  • 可以利用以上的特性,判断数组中 nan 的个数:np.count_nonzero(t != t)
  • 判断一个数字是否为 nan:np.isnan(a),返回 bool 类型
  • 把 nan 替换为0:t[np.isnan(t)] = 0
  • nan 和任何值计算都为 nan

NumPy 中常用统计函数

函数 说明
t.sum(axis=None) 求和
t.mean(axis=None) 均值,受离群点的影响较大
np.median(t, axis=None) 中值
t.max(axis=None) 最大值
t.min(axis=None) 最小值
np.ptp(t, axis=None) 极值,即最大值和最小值之差
t.std(axis=None) 标准差

默认返回多维数组的全部统计结果,如果指定 axis 则返回当前轴上的结果。

标准差:是一组数据平均值分散程度的一种度量。标准差越大,代表大部分数值和其平均值之间差异较大,数据波动越大越不稳定;标准差越小,代表这些数值较接近平均值,数据越稳定。

ndarray 缺失值填充均值

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
t = np.array([[  0.,   1.,   2.,   3.,   4.,   5.],
[ 6., 7., np.nan, 9., 10., 11.],
[ 12., 13., 14., np.nan, 16., 17.],
[ 18., 19., 20., 21., 22., 23.]])

def fill_nan_by_column_mean(t):
for i in range(t.shape[1]):
nan_num = np.count_nonzero(t[:, i][t[:, i] != t[:, i]])
if nan_num > 0: # 存在nan值
now_col = t[:, i]
now_col_not_nan = now_col[np.isnan(now_col) == False].sum()
now_col_mean = now_col_not_nan / (t.shape[0] - nan_num)
now_col[np.isnan(now_col)] = now_col_mean
t[:, i] = now_col

fill_nan_by_column_mean(t)
print(t)

数组的拼接

1
2
np.vstack((t1, t2))  # 竖直拼接
np.hstack((t1, t2)) # 水平拼接

数组的行列交换

1
2
t[[1, 2], :] = t[[2, 1], :]  # 行交换
t[:, [0, 2]] = t[:, [2, 0]] # 列交换

NumPy 更多好用的方法

1
2
3
4
5
6
7
8
9
10
11
12
# 获取最大值最小值的位置
np.argmax(t, axis=0)
np.argmin(t, axis=1)

# 创建一个全0的数组
np.zeros((3, 4))

# 创建一个全1的数组
np.ones((3, 4))

# 创建一个对角线为1的正方形数组(方阵)
np.eye(3)

生成随机数

1
2
3
4
5
6
7
8
# 生成0-1之间的随机数
np.random.rand(3, 4)

# 生成正态分布的随机数
np.random.randn(3, 4)

# 生成指定范围的随机整数
np.random.randint(0, 10, (3, 4))

copy 和 view 的区别

  1. a = b:完全不复制,a 和 b 相互影响
  2. a = b[:]:视图操作,会创建新的对象 a,但 a 的数据完全由 b 保管,两者数据变化一致
  3. a = b.copy():复制,a 和 b 互不影响

本站由 sswfive 使用 Stellar 1.42.0 主题创建。
本博客所有文章除特别声明外,均采用 CC BY-NC-SA 4.0 许可协议,转载请注明出处。

本站总访问量