Numpy
Numpy介绍
Numpy是一个开源的Python科学计算库,用于快速处理任意维度的数组。
Numpy支持常见的数组和矩阵操作。对于同样的数值计算任务,使用Numpy比直接使用Python要简洁的多。
Numpy使用ndarray对象来处理多维数组,该对象是一个快速而灵活的大数据容器。
NumPy的优势
- 对于同样的数值计算任务,使用NumPy要比直接编写Python代码便捷得多;
- NumPy中 的数组的存储效率和输入输出性能均远远优于Python中等价的基本数据结构,且其能够提升的性能是 与数组中的 元素成比例的;
- NumPy的大部分代码都是用C语言写的,其底层算法在设计时就有着优异的性能,这使得NumPy比纯Python代 码高 效得多
安装
NumPy 的Ndarray 对象
import numpy as np
list1 = [1,2,3,4]
oneArray = np.array(list1)
print(type(oneArray))#<class 'numpy.ndarray'>
print(oneArray)#[1 2 3 4]
numpy的使用
常用属性
list2 = [[1,2],[3,4],[5,6]]
Array1= np.array(list2)
print(Array1.ndim)# 获取数组的维度 2
print(Array1.shape)# 形状(行,列)(3,2)
print(Array1.size)# 有多少个元素 6
print(Array1.dtype)# 数据类型 int64
print(Array1.itemsize)# 元素字节数 8
dtype 是 NumPy 数组的一个属性,代表“数据类型”。
Array1 是一个二维数组,形状为 (3, 2),但 dtype 只关心元素类型,不关心维度。
- 在Python中,整数(int)是任意精度的,可以表示非常大的数。
- 在NumPy中,为了更精确地控制内存和计算性能,将数值类型划分得更细。为了效率和内存使用,整数类型有固定的位数,比如int8、int16、int32、int64,分别表示8位、16位、32位、64位的整数。同理,浮点数也有float16、float32、float64等。例如,
int64可以表示从 -9223372036854775808 到 9223372036854775807 的整数。所以有可能会溢出的。
为什么要有这么多类型?
因为不同的应用场景需要不同的精度和内存。例如,如果知道数组中的值都是很小的整数(比如在0到255之间),那么可以使用int8来节省内存。而在科学计算中,可能需要高精度的浮点数,所以使用float64。
调整数组形状
four = np.array([[1,2,3],[4,5,6]])
# 修改的是原有的
four.shape = (3,2)
print(four)#[[1 2] [3 4] [5 6]]
# 返回一个新的数组
four = four.reshape(3,2)
print(four)# [[1 2] [3 4] [5 6]]
# 将多维变成一维数组
five = four.reshape((6,),order='C')
# 默认情况下‘C’以行为主的顺序展开,‘F’(Fortran风格)意味着以列的顺序展开
# 将多维变成一维数组 flatten只能展平
six = four.flatten(order='C')
print(five) # [1 2 3 4 5 6]
print(six) # [1 2 3 4 5 6]
[[[ 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,里面有两个元素,分别是:
[[ 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,里面有3个元素.
[]是轴2,里面有4个元素。
掌握每个轴代表的含义对于机器学习是很重要的
NumPy的数据类型
import random
f = np.array([1,2,3,4,5], dtype = np.int16)#在生成ndarray的时候直接设置数据类型
print(f.itemsize) #字节数 2
print(f.dtype) #数据类型 int16
f1 = f.astype(np.int64) # 调整数据类型
print(f1.dtype)# int64
# 拓展随机生成小数
list4=[round(random.random(),2) for i in range(10)]# 使用python的round,保留两位
print(list4)
# list5=[random.random()for i in range(10)]
# print(round(list5,2)) # 错误 list没有round方法
arr = np.array([random.random() for i in range(10)])
print(np.round(arr,2))# 使用ndarray的round,保留两位
数组的计算
数组和数的计算
t1 =np.arange(24).reshape((6,4))
print(t1+2)
print("-"*20)
print(t1*2)
print("-"*20)
print(t1/2)
数组与数组之间的操作
t1 = np.arange(24).reshape((6,4))
t2 = np.arange(100,124).reshape((6,4))
print(t1+t2)
print(t1 t2)
t1 = np.arange(24).reshape((4,6))
t2 = np.arange(18).reshape((3,6))
print(t1)
print(t2)
print(t1-t2)
'''
ValueError: operands could not be broadcast together with shapes (4,6) (3,6)
'''
特殊情况:
行形状相同(会与每一行数组的对应位相操作)
列形状相同(会与每一个相同维度的数组的对应位相操作)具体如下
全面讲解NumPy广播规则
NumPy的广播(broadcasting)机制允许不同形状的数组进行数学运算。
广播的核心思想是:将较小的数组“广播”到较大数组的形状,以便它们具有兼容的形状进行逐元素运算。
规则如下:
规则1:从最右边的维度开始,向左逐个维度比较两个数组的形状。
规则2:两个维度兼容的条件是:
-
它们相等
-
其中一个维度是1
-
其中一个维度不存在(即其中一个数组的维度数较少)
规则3:如果所有维度都兼容,则可以广播。广播后,每个维度的大小是两者中较大的那个。
重要补充:
-
如果两个数组的维度数不同,那么维度较少的数组会在其前面(左边)补1,直到维度数相同。
-
对于每一个大小为1的维度,则沿该维度复制数据(虚拟复制)以匹配另一个数组的对应维度大小。
广播规则逐步分析
示例1:二维数组与一维数组
import numpy as np
A = np.array([[1, 2, 3],
[4, 5, 6]]) # 形状 (2, 3)
B = np.array([10, 20, 30]) # 形状 (3,)
# 步骤1: B的维度数较少,在其前面补1 -> 形状变为 (1, 3)
# 步骤2: 比较维度:
# 第一维:A是2,B是1 -> 兼容(因为B为1),广播后为2
# 第二维:A是3,B是3 -> 兼容(相等),广播后为3
# 步骤3: 广播后B的形状变为 (2, 3),相当于复制第一行得到 [[10,20,30], [10,20,30]]
print("A + B:")
print(A + B) # [[11,22,33], [14,25,36]]
示例2:三维数组与二维数组
A = np.arange(24).reshape(2,3,4) # 形状 (2,3,4)
B = np.arange(12).reshape(3,4) # 形状 (3,4)
# 步骤1: B的维度数较少,在其前面补1 -> 形状变为 (1,3,4)
# 步骤2: 比较维度:
# 第一维:A是2,B是1 -> 兼容,广播后为2
# 第二维:A是3,B是3 -> 兼容,广播后为3
# 第三维:A是4,B是4 -> 兼容,广播后为4
# 步骤3: 广播后B的形状变为 (2,3,4),相当于在第一个维度上复制一次
print("A + B:")
print(A + B)
示例3:维度大小1的广播
A = np.array([[1, 2, 3],
[4, 5, 6]]) # 形状 (2, 3)
B = np.array([[10], # 形状 (2, 1)
[20]])
# 步骤1: 两个数组维度数相同,直接比较
# 步骤2: 比较维度:
# 第一维:A是2,B是2 -> 兼容,广播后为2
# 第二维:A是3,B是1 -> 兼容(B为1),广播后为3
# 步骤3: 广播后B的形状变为 (2,3),相当于将每一列复制3次
print("A + B:")
print(A + B)
# 相当于 A + [[10,10,10], [20,20,20]]
示例4:两个数组都需要广播
A = np.arange(6).reshape(2,3,1) # 形状 (2,3,1)
B = np.arange(12).reshape(1,3,4) # 形状 (1,3,4)
# 比较维度:
# 第一维:A是2,B是1 -> 兼容,广播后为2
# 第二维:A是3,B是3 -> 兼容,广播后为3
# 第三维:A是1,B是4 -> 兼容(A为1),广播后为4
# 广播后A的形状变为 (2,3,4),B的形状也变为 (2,3,4)
print("A + B 的形状:", (A + B).shape) # (2,3,4)
轴(对哪个轴进行运算哪个轴就没了)
对哪一维进行运算就是对就是将那一维的说有元素对应相加到一起
a=np.arange(27).reshape((3,3,3))
b=np.sum(a, axis=0)
print(b)
c=np.sum(a, axis=1)
print(c)
d=np.sum(a, axis=2)
print(d)
切片和索引
一维(和list一样)
import numpy as np
a = np.arange(10)
print(a[2:7:2])# [2 4 6 8]
print(a[2],a)# 2 [0 1 2 3 4 5 6 7 8 9]
print(a[2:])# [2 3 4 5 6 7 8 9]
多维
t1 = np.arange(24).reshape(4,6)
print(t1)
[[ 0 1 2 3 4 5]
[ 6 7 8 9 10 11]
[12 13 14 15 16 17]
[18 19 20 21 22 23]]
对数组取值。
t1[ : , : ], ","前面对应第一维,后面对应第二维。如果是高维数组就以此类推。
t1[0] 取第1行,t1[1]:取第2行
t1[1:] 从第二行开始连续的取到最后
t1[1:3,:] 取第2-4行
t1[[0,2,3]] 取第1、3、4行
t1[:,1] 取第二列
t1[:,1:]) 从第二列开始连续的取到最后
t1[:,[0,2,3]]取第1、3、4列
[[ 0 2 3]
[ 6 8 9]
[12 14 15]
[18 20 21]]
t1[2,3] 取某一个值,三行四列
修改值
t[:, 1:4] = 0 将第2行到第5行的元素全变成0
t[1:4 , 2:5]=0 修改多行多列,取第二行到第四行,第三列到第五列
t[[0,1] , [0,3]]=0 修改多个不相邻的点
t[(t > 2) & (t < 6)] = 0 # 与 将大于2小于6的元素全部改为0
t[(t < 2) | (t > 6)] = 0 # 或 将小于2和大于6的元素改为0
t[~(t > 6)] = 0 # 非 将大于6的元素改为0
t=t.clip(10,18) # 将小于10的元素改为10,大于18的元素改为18
数组的添加
append
如果没有指定轴,那么就会被展平之后添加
a = np.array([[1, 2, 3], [4, 5, 6]])
print(a)
print(np.append(a, [7, 8, 9]))#[1 2 3 4 5 6 7 8 9]
print(np.append(a, [[7, 8, 9]], axis=0))
#[[1 2 3]
# [4 5 6]
# [7 8 9]]
print(np.append(a, [[5, 5, 5], [7, 8, 9]], axis=1))
#[[1 2 3 5 5 5]
# [4 5 6 7 8 9]]
insert
如果没有指定轴,那么就会被展平之后添加
a = np.array([[1, 2], [3, 4], [5, 6]])
#未传递 Axis 参数。 在插入之前输入数组会被展开
print(np.insert(a, 3, [11, 12]))#[ 1 2 3 11 12 4 5 6]
如果是一个元素,则插入的元素会被广播
print(np.insert(a, 1, [11], axis=0))#如果是一个元素,则插入的元素会被广播
# [[ 1 2]
# [11 11]
# [ 3 4]
# [ 5 6]]
print(np.insert(a, 1, 11, axis=1))#[[ 1 11 2]
# [ 3 11 4]
# [ 5 11 6]]
数组中的删除delete
a = np.arange(12).reshape(3,4)
print(a)
print(np.delete(a,5))#未传递 Axis 参数。 在删除之前输入数组会被展开
print(np.delete(a,1,axis = 1))#删除每一行中的第二列
数组去重 unique
import numpy as np
a = np.array([5,2,6,2,7,5,6,8,2,9])
u = np.unique(a)#去重 [2 5 6 7 8 9]
u,indices = np.unique(a, return_index = True)#返回去重后的数组 和 去重后的数组对应的原数组对应下标
print (u,indices) # [2 5 6 7 8 9] [1 0 2 4 7 9]
u,indices = np.unique(a,return_inverse = True)#返回去重后的数组 和 原数组对应的去重后的数组下标
print (u,indices) #[2 5 6 7 8 9] [1 0 2 0 3 1 2 4 0 5]
u,indices = np.unique(a,return_counts = True) # 返回去重后的数组 和 去重后的数组在原数组中对应的出现的次数
print (u, indices) #[2 5 6 7 8 9] [3 2 2 1 1 1]
数学运算
最大值max,最小值min
import numpy as np
score = np.array([[80,88],[82,81],[75,81]])
print(np.max(score))#获取所有数据最大值 88
print(np.max(score,axis=0))# 获取第一个轴上的数据最大值 [82 88]
print(np.max(score,axis=1))# 获取第二个轴上的数据最大值 [88 82 81]
arr_1=np.arange(24).reshape(2,3,4)
print(arr_1)
print(np.max(arr_1,axis=0))
[[[ 0 1 2 3]
[ 4 5 6 7]
[ 8 9 10 11]]
[[12 13 14 15]
[16 17 18 19]
[20 21 22 23]]]
结果:
[[12 13 14 15]
[16 17 18 19]
[20 21 22 23]]
我们沿着axis=0(层方向)取最大值,就是比较两层中相同行、相同列的元素,取最大值。
axis参数指定了被消除的维度。我们沿着哪个轴操作,哪个轴就会被消除,而其他维度保留。
在这个例子中,沿着axis=0操作,原本的形状(2,3,4)中的2(层)被消去,结果形状就是(3,4)。
如果我们使用axis=1,那么就是沿着“行”方向操作,消去“行”这个维度,结果形状变为(2,4)。
即,对于每一层,我们比较每一列上的三个行元素,取最大值。
通用函数:
数组的拼接concatenate,stack
concatenate拼接的时候不会增维对哪个轴拼接哪个轴对应的值就会变大
a = np.array([[1,2],[3,4]])
b = np.array([[5,6],[7,8]])# 要求 a,b 两个数组的维度相同
print (np.concatenate((a,b),axis= 0)) #输出:[[1 2]
# [3 4]
# [5 6]
# [7 8]]
a = np.arange(24).reshape(2,3,4)
b = np.arange(24).reshape(2,3,4)# 要求 a,b 两个数组的维度相同
print(a)
print (np.concatenate((a,b),axis = 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]]]
输出:
[[[ 0 1 2 3]
[ 4 5 6 7]
[ 8 9 10 11]
[ 0 1 2 3]
[ 4 5 6 7]
[ 8 9 10 11]]
[[12 13 14 15]
[16 17 18 19]
[20 21 22 23]
[12 13 14 15]
[16 17 18 19]
[20 21 22 23]]]
stack拼接的时候会增维
a = np.array([[1,2],[3,4]])
b = np.array([[5,6],[7,8]])# 要求 a,b 两个数组的维度相同
print (np.stack((a,b),axis= 0))#输出:[[[1 2]
# [5 6]]
# [[3 4]
# [7 8]]]
print (np.stack((a,b),axis = 1))#输出:[[[1 2]
# [5 6]]
# [[3 4]
# [7 8]]]
数组的分割
按照哪个轴,哪个轴就发生变化
arr = np.arange(24).reshape(2,3,4)
print( arr)
b = np.split(arr,2,axis=0)
print (b)
b = np.split(arr,3,axis=1)
print (b)
b = np.split(arr,4,axis=2)
print (b)
[[[ 0 1 2 3]
[ 4 5 6 7]
[ 8 9 10 11]]
[[12 13 14 15]
[16 17 18 19]
[20 21 22 23]]]
[array([[[ 0, 1, 2, 3]],
[[12, 13, 14, 15]]]), array([[[ 4, 5, 6, 7]],
[[16, 17, 18, 19]]]), array([[[ 8, 9, 10, 11]],
[[20, 21, 22, 23]]])]
[array([[[ 0],
[ 4],
[ 8]],
[[12],
[16],
[20]]]), array([[[ 1],
[ 5],
[ 9]],
[[13],
[17],
[21]]]), array([[[ 2],
[ 6],
[10]],
[[14],
[18],
[22]]]), array([[[ 3],
[ 7],
[11]],
[[15],
[19],
[23]]])]
数组中nan和inf
NaN (Not a Number)
表示一个不确定的或无法表示的数字。例如,0除以0、无穷大减无穷大等操作会产生NaN。
-
特性:
-
NaN != NaN 为 True(即NaN不等于任何值,包括自己)
-
任何与NaN的算术运算结果通常都是NaN(除了某些函数如
nan_to_num可以处理) -
NaN 与任何值(包括自己)比较都返回 False,除了不等于运算符(!=)返回 True
-
用于表示缺失或无效的数据
-
-
产生原因:NaN 通常由无效的数学运算产生(如0/0、sqrt(-1)等)
Inf (Infinity)
表示无穷大,分为正无穷(+inf)和负无穷(-inf)。例如,一个非零数除以0会产生无穷大。
-
特性:
-
正无穷大于任何有限数,负无穷小于任何有限数
-
某些数学运算会产生无穷大,例如:1.0 / 0.0 产生 inf,-1.0 / 0.0 产生 -inf
-
无穷大可以进行有意义的比较,例如:5 < inf 为 True
-
-
产生原因:Inf 通常由除以零或溢出产生
np.nan和np.nan是不相等的
import numpy as np
# 创建一个 nan 和 inf #
a = np.nan
b = np.inf
print(a,type(a)) # nan <class 'float'>
print(b,type(b)) # inf <class 'float'>
print(np.isnan(a)) # True
print(np.isinf(b)) # True
print(np.nan==np.nan) # False 注意 这里
print(np.inf==np.inf) # True
print(True==1)# True
print(False==0)# True
1.我们可以利用这个特性判断 nan 的个数
t = np.arange(24,dtype=float).reshape(4,6)
t[3,4] = np.nan
print(t)
print(t!=t)
print(np.count_nonzero(t != t)) #输出1
[[ 0. 1. 2. 3. 4. 5.]
[ 6. 7. 8. 9. 10. 11.]
[12. 13. 14. 15. 16. 17.]
[18. 19. 20. 21. nan 23.]]
[[False False False False False False]
[False False False False False False]
[False False False False False False]
[False False False False True False]]
2.还可以利用这个特性对NaN进行替换:
如: 将 nan 替换为 0
t[np.isnan(t)] = 0# 将 nan 替换为 0
print(t)
如:将 nan 替换为该列平均值
for i in range(t.shape[1]):# 遍历每一列,然后判断每一列是否有 nan
temp_col = t[:,i]#获取当前列数据
nan_num = np.count_nonzero(temp_col != temp_col)# 判断当前列中是否含有 nan
if nan_num != 0:# 如果含有 nan
# 将这一列不为 nan 的数据拿出来
temp_col_not_nan = temp_col[temp_col == temp_col]
# 将 nan 替换成这一列的平均值
temp_col[np.isnan( temp_col )] = np.mean( temp_col_not_nan )
print(t)
temp_col == temp_col 会生成一个布尔掩码,其中非NaN的位置为True,NaN的位置为False。
然后,当我们使用这个布尔掩码来索引数组temp_col时,即temp_col[temp_col == temp_col],就会得到所有对应掩码为True的元素,也就是所有非NaN的元素。
np.inf和np.inf是相等的
print(np.inf==np.inf)# True
print(np.inf>np.inf)# False
二维数组的转置np.transpose(数组) ,数组.T
import numpy as np
a = np.arange(12).reshape(3,4)
print (a )
print (np.transpose(a))
print (a.T)
轴交换(用于三维及以上)
a = np.arange(24).reshape(2,3,4)
print (a )
print (np.swapaxes(a,0,1))
轴滚动np.rollaxis()(将某个轴放到弄个轴之前)
a = np.arange(120).reshape(2,3,4,5)
print (np.rollaxis(a,3,1).shape)#(2, 5, 3, 4)把三轴放到一轴之前
print (np.rollaxis(a,1,4).shape)#(2, 4, 5, 3)把一轴放到四轴之前
numpy生成随机数

numpy读取数据处理数据
.csv 和 .txt 文件格式的区别
1. 基本定义
-
.txt(文本文件):一种最通用的文本文件格式,可以包含任意类型的文本内容,没有固定的结构。
-
.csv(也是文本文件逗号分隔值):一种特殊的文本文件格式,用逗号分隔数据字段,通常用于存储表格数据(如电子表格、数据库)。
2. 主要区别
| 特性 | .csv 文件 | .txt 文件 |
|---|---|---|
| 结构 | 有结构,通常每行代表一条记录,每列用分隔符(如逗号)分隔 | 无固定结构,可以是任意文本 |
| 用途 | 专门用于存储表格数据,便于程序(如Excel、pandas)解析 | 存储任意文本信息,如日志、配置文件、文档等 |
| 分隔符 | 通常使用逗号,但也可以使用其他字符(如制表符、分号) | 无固定分隔符,可以自由定义 |
| 标准性 | 有基本的标准(如RFC 4180),但存在变体(如分隔符、引号规则) | 无标准,完全取决于具体应用 |
| 可读性 | 如果用文本编辑器打开,数据排列整齐,但不如专业表格软件直观 | 直接可读,但若数据无格式可能难以理解 |
| 程序处理 | 许多编程语言有专门的库(如Python的csv模块、pandas) | 通常按行读取,需要自行解析内容 |
numpy读取数据
t_us = np.loadtxt(us_file_path,delimiter=",",dtype="int"),这样读取的t_us是一个二维数组,每一行对应文件中的一行数据(读取每一行中用逗号分隔的多个整数)。
import numpy as np
from matplotlib import pyplot as plt
us_file_path = "./youtube_video_data/US_video_data_numbers.csv"
uk_file_path = "./youtube_video_data/GB_video_data_numbers.csv"
# t1 = np.loadtxt(us_file_path,delimiter=",",dtype="int",unpack=True)
t_us = np.loadtxt(us_file_path,delimiter=",",dtype="int")
t_us_comments = t_us[:,-1]# 取美国电影评论的数据
# 怎么知道分多少组,打印最大和最小值
print(t_us_comments.max(),t_us_comments.min())#582624 0
print(t_us_comments[t_us_comments>5000].shape)# 打印大于评论数100000 的数据形状:(315,)
t_us_comments=t_us_comments[t_us_comments<5000]# 只保留小于5000的评论数
d = 50
bin_nums = (t_us_comments.max()-t_us_comments.min())//d
# 绘图
plt.figure(figsize=(20,8),dpi=80)
plt.hist(t_us_comments,bin_nums)
plt.show()
AtomGit 是由开放原子开源基金会联合 CSDN 等生态伙伴共同推出的新一代开源与人工智能协作平台。平台坚持“开放、中立、公益”的理念,把代码托管、模型共享、数据集托管、智能体开发体验和算力服务整合在一起,为开发者提供从开发、训练到部署的一站式体验。
更多推荐



所有评论(0)