numpy

1.什么是numpy

一个在Python中做科学计算的基础库,重在数值计算,也是大部分PYTHON科学计算库的基础库,多用于在大型、多维数组上执行数值运算

2.安装

1
pip install numpy

3.基本使用

1.numpy创建数组(矩阵)

1
2
3
4
5
6
7
8
import numpy as np
import random

# 使用numpy生成数组,type得到ndarray的数据类型

t1 = np.array([1, 2, 3])
print("t1", t1)
print(type(t1))
1
2
t1 [1 2 3]
<class 'numpy.ndarray'>
1
2
3
t2 = np.array(range(10))
print("t2", t2)
print(type(t2))
1
2
t2 [0 1 2 3 4 5 6 7 8 9]
<class 'numpy.ndarray'>

2.numpy中常见的数组类型

image-20230117141556064

1
2
3
4
5
t3 = np.arange(4, 10, 2)
print("t3", t3)
print(type(t3))
# dtype数据的类型
print(t3.dtype)
1
2
3
t3 [4 6 8]
<class 'numpy.ndarray'>
int32
1
2
3
4
# 可以使用dtype指定数据的类型(即多少位一个字节)
t4 = np.array(range(1, 4), dtype=float)
print("t4", t4)
print(t4.dtype)
1
2
t4 [1. 2. 3.]
float64
1
2
3
4
# numpy中的Boolean类型
t5 = np.array([1, 1, 0, 1, 0, 0], dtype=bool)
print("t5", t5)
print(t5.dtype)
1
2
t5 [ True  True False  True False False]
bool
1
2
3
4
# 调整数据类型
t6 = t5.astype("int8")
print("t6", t6)
print(t6.dtype)
1
2
t6 [1 1 0 1 0 0]
int8
1
2
3
4
# numpy中的小数
t7 = np.array([random.random() for i in range(10)])
print("t7", t7)
print(t7.dtype)
1
2
3
t7 [0.84161528 0.96569646 0.53128828 0.52827078 0.46984309 0.84778391
0.19475405 0.75765394 0.39033226 0.18261529]
float64
1
2
t8 = np.round(t7, 2)
print("t8", t8)
1
t8 [0.84 0.97 0.53 0.53 0.47 0.85 0.19 0.76 0.39 0.18]

3.不同维度数组

1
2
3
4
5
# 一维
t9 = np.arange(12)
print("t9", t9)
# shape展示数据的形状
print(t9.shape)
1
2
t9 [ 0  1  2  3  4  5  6  7  8  9 10 11]
(12,)
1
2
3
4
# 二维
t10 = np.array([[1, 2, 3], [4, 5, 6]])
print("t10", t10)
print(t10.shape)
1
2
3
t10 [[1 2 3]
[4 5 6]]
(2, 3)
1
2
3
4
5
6
7
# 三维
t11 = np.array([[[1, 2, 3], [4, 5, 6]], [[7, 8, 9], [10, 11, 12]]])
print("t11", t11)
print(t11.shape)

t12 = np.arange(12)
print("t12", t12)
1
2
3
4
5
6
t11 [[[ 1  2  3]
[ 4 5 6]]
[[ 7 8 9]
[10 11 12]]]
(2, 2, 3)
t12 [ 0 1 2 3 4 5 6 7 8 9 10 11]

4.维度转换

1
2
3
4
# 一维转二维
t13 = t12.reshape(3, 4)
print("t13", t13)
print("---------------")
1
2
3
t13 [[ 0  1  2  3]
[ 4 5 6 7]
[ 8 9 10 11]]
1
2
3
4
# 一维转三维
t14 = np.array(range(24)).reshape(2, 3, 4)
print("t14", t14)
print("---------------")
1
2
3
4
5
6
t14 [[[ 0  1  2  3]
[ 4 5 6 7]
[ 8 9 10 11]]
[[12 13 14 15]
[16 17 18 19]
[20 21 22 23]]]
1
2
3
# 三维转二维
t15 = t14.reshape(4, 6)
print("t15", t15)
1
2
3
4
t15 [[ 0  1  2  3  4  5]
[ 6 7 8 9 10 11]
[12 13 14 15 16 17]
[18 19 20 21 22 23]]
1
2
3
# 二维转一维
t16 = t15.reshape(24)
print("t16", t16)
1
t16 [ 0  1  2  3  4  5  6  7  8  9 10 11 12 13 14 15 16 17 18 19 20 21 22 23]
1
2
# flatten将数组展开成一维数组
print(len(t14.flatten()))
1
24

4.数组的运算

1.数组和数的计算

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
import numpy as np

# 数组与数的计算(对每一个值进行计算)
t1 = np.array(range(10))
print("t1", t1)
# 数组的加法
t2 = t1 + 2
print("数组与数的加法", t2)

# 数组的减法
t3 = t1 - 1
print("数组与数的减法", t3)

# 数组的乘法
t4 = t1 * 3
print("数组与数的乘法", t4)

# 数组的除法
t5 = t1 / 2
print("数组与数的除法", t5)
1
2
3
4
5
t1 [0 1 2 3 4 5 6 7 8 9]
数组与数的加法 [ 2 3 4 5 6 7 8 9 10 11]
数组与数的减法 [-1 0 1 2 3 4 5 6 7 8]
数组与数的乘法 [ 0 3 6 9 12 15 18 21 24 27]
数组与数的除法 [0. 0.5 1. 1.5 2. 2.5 3. 3.5 4. 4.5]

2.数组和数组的计算

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
# 数组与数组之间的计算(列数相同或者行数相同就可以进行计算)
t6 = np.arange(1, 25).reshape(4, 6)

t7 = np.arange(100, 124).reshape(4, 6)
print("t7", t7)

t8 = t6 + t7
print("数组与数组的加法\n", t8)

t9 = t7 - t6
print("数组与数组的减法\n", t9)

t10 = t6 * t7
print("数组与数组的乘法\n", t10)

t11 = t7 // t6
print("数组与数组的除法\n", t11)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
t6 [[ 1  2  3  4  5  6]
[ 7 8 9 10 11 12]
[13 14 15 16 17 18]
[19 20 21 22 23 24]]
t7 [[100 101 102 103 104 105]
[106 107 108 109 110 111]
[112 113 114 115 116 117]
[118 119 120 121 122 123]]
数组与数组的加法
[[101 103 105 107 109 111]
[113 115 117 119 121 123]
[125 127 129 131 133 135]
[137 139 141 143 145 147]]
数组与数组的减法
[[99 99 99 99 99 99]
[99 99 99 99 99 99]
[99 99 99 99 99 99]
[99 99 99 99 99 99]]
数组与数组的乘法
[[ 100 202 306 412 520 630]
[ 742 856 972 1090 1210 1332]
[1456 1582 1710 1840 1972 2106]
[2242 2380 2520 2662 2806 2952]]
数组与数组的除法
[[100 50 34 25 20 17]
[ 15 13 12 10 10 9]
[ 8 8 7 7 6 6]
[ 6 5 5 5 5 5]]

5.轴(axis)

在numpy中可以理解为方向,使用0,1,2…数字表示,对于一个一维数组,只有一个0轴,对于2维数组(shape(2,2)),有0轴和1轴,对于三维数组(shape(2,2, 3)),有0,1,2轴

有了轴的概念之后,我们计算会更加方便,比如计算一个2维数组的平均值,必须指定是计算哪个方向上面的数字的平均值

image-20230117143357482

image-20230117143438408

6.读取数据

CSV:Comma-Separated Value,逗号分隔值文件

显示:表格状态

源文件:换行和逗号分隔行列的格式化文本,每一行的数据表示一条记录

由于csv便于展示,读取和写入,所以很多地方也是用csv的格式存储和传输中小型的数据,我们会经常操作csv格式的文件,但是操作数据库中的数据也是很容易的实现的

np.loadtxt(fname,dtype=np.float,delimiter=None,skiprows=0,usecols=None,unpack=False)读取数据

参数 解释
frame 文件、字符串或产生器,可以是.gz或bz2压缩文件
dtype 数据类型,可选,CSV的字符串以什么数据类型读入数组中,默认np.float
delimiter 分隔字符串,默认是任何空格,改为逗号
skiprows 跳过前x行,一般跳过第一行表头
usecols 读取指定的列,索引,元组类型
unpack 如果True,读入属性将分别写入不同数组变量,False读入数据只写入一个数组变量,默认False

有一个英国和美国各自youtube1000多个视频的点击,喜欢,不喜欢,评论数量([“views”,”likes”,”dislikes”,”comment_total”])的csv用loadtxt来对其进行操作

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
import numpy as np

# 视频的点击,喜欢,不喜欢,评论数量

us_file_path = "./youtube_video_data/US_video_data_numbers.csv"
uk_file_path = "./youtube_video_data/GB_video_data_numbers.csv"

# delimiter分隔字符串,默认是空格
# dtype数据类型,默认是numpy.float
# unpack将数组进行转置(可以将列变为行)
t1 = np.loadtxt(us_file_path, delimiter=",", dtype="int", unpack=True)
t2 = np.loadtxt(us_file_path, delimiter=",", dtype="int")

print(t1)
print("--------------------------------------------------------")
print(t2)
1
2
3
4
5
6
7
8
9
10
11
12
[[4394029 7860119 5845909 ...  142463 2162240  515000]
[ 320053 185853 576597 ... 4231 41032 34727]
[ 5931 26679 39774 ... 148 1384 195]
[ 46245 0 170708 ... 279 4737 4722]]
--------------------------------------------------------
[[4394029 320053 5931 46245]
[7860119 185853 26679 0]
[5845909 576597 39774 170708]
...
[ 142463 4231 148 279]
[2162240 41032 1384 4737]
[ 515000 34727 195 4722]]
  • delimiter:指定边界符号是什么,不指定会导致每行数据为一个整体的字符串而报错
  • dtype:默认情况下对于较大的数据会将其变为科学计数的方式
  • upack:默认是Flase(O),默认情况下,有多少条数据,就会有多少列

​ 为True(1)的情况下,每一列的数据会组成一行,原始数据有多少列,加载出来的数据就会有多少行,相当于
转置的效果

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

其他的转置方法

1
2
3
4
5
6
7
8
9
10
t3 = np.arange(24).reshape(4, 6)
print("-----------")
print(t3)
print("-----transpose将数组转置-----")
print(t3.transpose())
print("-----T转置-----")
print(t3.T)
# swapaxes交换轴的位置
print("-----swapaxes转置-----")
print(t3.swapaxes(1, 0))
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
[[ 0  1  2  3  4  5]
[ 6 7 8 9 10 11]
[12 13 14 15 16 17]
[18 19 20 21 22 23]]
-----transpose将数组转置-----
[[ 0 6 12 18]
[ 1 7 13 19]
[ 2 8 14 20]
[ 3 9 15 21]
[ 4 10 16 22]
[ 5 11 17 23]]
-----T转置-----
[[ 0 6 12 18]
[ 1 7 13 19]
[ 2 8 14 20]
[ 3 9 15 21]
[ 4 10 16 22]
[ 5 11 17 23]]
-----swapaxes转置-----
[[ 0 6 12 18]
[ 1 7 13 19]
[ 2 8 14 20]
[ 3 9 15 21]
[ 4 10 16 22]
[ 5 11 17 23]]

7.numpy索引和切片

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
数组[行,列]      取指定的某行的某列元素
如:arange[1,2] 取第二行第三列的数据

数组[:,列] 取指定的某列的数据
如:arange[:,2] 取第三列的所有数据
如:arange[:,[0,2,7]] 取第一、三、八列的所有数据

数组[:,开始:结束:步长] 取从指定位置开始到指定位置结束的步长的所有列的值
如:arange[:,5:] 取从第四列开始所有列的值
如:arange[:,0:10:2] 取从0到10步长为2的所有列的值

数组[行,:] 取指定的某行的数据
如:arange[2,:] 取第三行的所有数据
如;arange[[0,3,9],:] 取第一、四十行的所有数据

数组[开始:结束:步长,:] 取从指定位置开始,到指定位置结束的步长的所有行的值
如:arange[5:,:] 取从第四行开始所有行的值
如:arange[0:10:2,:] 取从0到10步长为2的所有行的值

数组[开始:结束:步长,开始:结束:步长]取从指定位置开始,到指定位置结束的步长的行的指定位置开始,到指定位置结束的步长的列的值
如:arange[2:,2] 取从第三行开始所有的第三列的值
如:arange[2:,2:] 取从第三行开始所有第三列及之后列的值
如:arange[2:,2:5] 取从第三行开始所有第三列到第五列的的值
如:arange[2:,0:10:2] 取从第三行开始从0到10步长为2的所有列的值
如:arange[2,2:] 取第三行所有第三列及之后列的值
如:arange[2:10,2:] 取第三行到第十行的第三列及之后列的值
如:arange[0:10:2,2] 取从0到10步长为2行所有第三列的值
如:arange[0:10:2,2:] 取从0到10步长为2行所有第三列及之后列的值

数组[[指定的行数],[指定的列数]] 取需要的行数和列数
如:arange[[1,4],[4,6]] 取第二行第五列的值和第五行第七列的值

1.numpy中数值的修改

对取到的值使用=来进行修改值

2.numpy中布尔索引

按条件来进行修改值(选中结果为True的)

1
2
数组[条件] = 修改的值
如:arange[arange < 100] = 50 即将数组中小于100的数修改成50

3.numpy中的三元运算符

1
2
numpy.where(条件,正确修改的值,错误修改的值)
如:numpy.where(arange < 50,10,20) 即将数组中小于50的修改为10,大于50的修改为20

4.numpy中的clip(裁剪)

1
2
numpy.clip[裁剪的数组,最小的值,最大的值]即将小于最小的值修改为最小的值,将大于最大的值修改为最大的值
如:numpy.clip[arange,4,6] 即将小于4的值修改为4,将大于6的值修改为6

5.numpy中的nan和inf

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

什么时候numpy中会出现nan:

​ 当我们读取本地的文件为float的时候,如果有缺失,就会出现nan

​ 当做了一个不合适的计算的时候(比如无穷大(inf)减去无穷大)

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

什么时候会出现inf包括(-inf,+inf)

​ 比如一个数字除以0,(python中直接会报错,numpy中是一个inf或者-inf)

6.numpy中的nan的注意点

  • 两个nan是不相等的
1
2
numpy.nan == numpy.nan  False
numpy.nan != numpy.nan True
  • count_nonzero统计数组中非零元素的个数

    由于nan不等于nan,所以为False,且False为1,所以count_nonzero可以统计数组中nan的个数

1
numpy.count_nonzero(arange != arange)
  • 判断是否为nan
1
numpy.isnan(arange)
  • nan和任何值计算都为nan

7.numpy中常用统计函数

方法 函数 作用
求和 numpy.sum(数组,轴) 求整个数组的和或数组的某行某列的和
均值 numpy.mean(数组,轴) 受离群点的影响较大
中值 numpy.median(数组,轴)
最大值 numpy.max(数组,轴)
最小值 numpy.min(数组,轴)
极值 numpy.ptp(数组,轴) 即最大值和最小值之差
标准差 numpy.std(数组,轴) 标准差是一组数据平均值分散程度的一种度量。一个较大的标准差,代表大部分数值和其平均值之间差异较大;一个较小的标准差,代表这些数值较接近平均值反映出数据的波动稳定情况,越大表示波动越大,约不稳定

8.numpy缺失值填充均值

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
import numpy as np

def fill_ndarray(t1):
for i in range(t1.shape[1]): # 遍历每一列
temp_col = t1[:, i] # 当前的一列
nan_num = np.count_nonzero(temp_col != temp_col)
if nan_num != 0: # 不为0,说明当前这一列中有nan
temp_not_nan_col = temp_col[temp_col == temp_col] # 当前一列不为nan的array
temp_col[np.isnan(temp_col)] = np.mean(
temp_not_nan_col
) # 选中当前为nan的位置,把值赋值为不为nan的均值
return t1

if __name__ == "__main__":
t1 = np.arange(12)
t1 = np.reshape(t1, (3, 4))
print("t1", t1)
t1 = t1.astype(float)
print("-" * 30)

t1[1, 2:] = np.nan
print("t1", t1)
print("-" * 30)

t1 = fill_ndarray(t1)
print("new t1", t1)
1
2
3
4
5
6
7
8
9
10
11
t1 [[ 0  1  2  3]
[ 4 5 6 7]
[ 8 9 10 11]]
------------------------------
t1 [[ 0. 1. 2. 3.]
[ 4. 5. nan nan]
[ 8. 9. 10. 11.]]
------------------------------
new t1 [[ 0. 1. 2. 3.]
[ 4. 5. 6. 7.]
[ 8. 9. 10. 11.]]

9.数组的拼接

1
2
numpy.vstack((arange1,arange2))   竖直拼接
numpy.hstack((arange1,arange2)) 水平拼接
1
2
3
4
5
6
7
8
9
10
11
12
13
import numpy as np

t1 = np.arange(12).reshape(3, 4)
t2 = np.arange(12, 24).reshape(3, 4)

print("t1", t1)
print("t2", t2)

vertically = np.vstack((t1, t2))
print("竖直拼接\n", vertically)

horizontally = np.hstack((t1, t2))
print("水平拼接\n", horizontally)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
t1 [[ 0  1  2  3]
[ 4 5 6 7]
[ 8 9 10 11]]
t2 [[12 13 14 15]
[16 17 18 19]
[20 21 22 23]]
竖直拼接
[[ 0 1 2 3]
[ 4 5 6 7]
[ 8 9 10 11]
[12 13 14 15]
[16 17 18 19]
[20 21 22 23]]
水平拼接
[[ 0 1 2 3 12 13 14 15]
[ 4 5 6 7 16 17 18 19]
[ 8 9 10 11 20 21 22 23]]

10.数组的行列交换

1
2
3
4
5
6
7
8
t1 = np.arange(12).reshape(3, 4)
t2 = np.arange(12, 24).reshape(3, 4)

t1[[1, 2], :] = t1[[2, 1], :]
print("行交换\n", t1)

t2[:, [0, 2]] = t2[:, [2, 0]]
print("列交换\n", t2)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
t1 [[ 0  1  2  3]
[ 4 5 6 7]
[ 8 9 10 11]]
t2 [[12 13 14 15]
[16 17 18 19]
[20 21 22 23]]

行交换
[[ 0 1 2 3]
[ 8 9 10 11]
[ 4 5 6 7]]
列交换
[[14 13 12 15]
[18 17 16 19]
[22 21 20 23]]

11.numpy更多好用的方法

  1. 获取最大值最小值的位置
    1. numpy.argmax(arange,axis=0)
    2. numpy.argmin(arange,axis=1)
  2. 创建一个全0的数组: numpy.zeros((3,4))
  3. 创建一个全1的数组:numpy.ones((3,4))
  4. 创建一个对角线为1的正方形数组(方阵):numpy.eye(3)

12.numpy生成随机数

方法 解释
.rand(d0,d1,…dn) 创建d0-dn维度的均匀分布的随机数数组,浮点数,范围从0-1
.randn(d0,d1,…dn) 创建d0-dn维度的标准正态分布随机数,浮点数,平均数0,标准差1
.randint(low,high,(shape)) 从给定上下限范围选取随机整数,范围是low,high,形状是shape
.uniform(low,high,(size)) 产生具有均匀分布的数组,low起始值,high结束值,size形状
.normal(loc,scale,(size)) 从指定正态分布中随机抽取样本,分布中心是loc(概率分布的均值),标准差是scale,形状是size
.seed(s) 随机数种子,s是给定的种子值。因为计算机生成的是伪随机数,所以通过设定相同的随机数种子,可以每次生成相同的随机数

13.numpy的注意点copy和view

1.a=b 完全不复制,a和b相互影响

2.a = b[:],视图的操作,一种切片,会创建新的对象a,但是a的数据完全由b保管,他们两个的数据变化是一致的,

3.a = b.copy(),复制,a和b互不影响