numpy学习笔记

Numpy

链接:https://www.bilibili.com/video/BV1tA411H7cQ?p=1
官方文档:https://numpy.org/doc/stable/user/

  • 安装
    通过pip install numpy即可安装
  • 引入
    通过import numpy as np引入

Numpy中的数组

  • numpy中的数组的数据类型必须全部一致
  • 数组可以是多维的,相当于矩阵,可进行相互运算

创建数组(np.ndarray对象)

  1. 使用np.arry来创建数组
a = np.array([1, 2, 3, 4])
print(a)
# [1 2 3 4]
  1. 使用np.arange创建数组,类似于python中的range()
a = np.arange(10)
print(a)
# [0 1 2 3 4 5 6 7 8 9]
  1. 使用np.random生成随机数数组
a1 = np.random.random((2, 2))  # 生成2行2列的0~1随机数数组
a2 = np.random.randint(0, 10, size=(3, 3))  # 生成3行3列0~10之间的整数
  1. 使用函数生成特殊的数组
a1 = np.zeros((2, 2))  # 生成2x2的全是0的数组
a2 = np.ones((3, 2))  # 生成3x2的全是1的数组
a3 = np.full((3, 3), 8)  # 生成3x3的全是8的数组
a4 = np.eye(3)  # 生成3x3的单位矩阵

数组常用属性

ndarray.dtype

数组中只能存储同一种数据类型,可以通过dtype获取数组中元素的数据类型。一下是常用数据类型:

数据类型描述唯一标识符
bool用一个字节存储的布尔类型(True或False)‘b’
int8一个字节大小,-128至127‘i1’
int1616位整数,-215至215-1‘i2’
int32(默认)32位整数,-231至231-1‘i4’
int6464位整数,-263至263-1‘i8’
uint8无符号整数,0至255‘u1’
uint16无符号整数,0至216-1‘u2’
uint32无符号整数,0至232-1‘u4’
uint64无符号整数,0至264-1‘u8’
float1616位半精度浮点数‘f2’
float3232位单精度浮点数‘f4’
float6464位双精度浮点数‘f8’
complex64复数,分别用两个32位浮点数表示实部虚部‘c8’
complex128复数,分别用两个64位浮点数表示实部虚部‘c16’
object_python对象‘O’
string_字符串‘S’
unicode_unicode类型‘U’
  1. 指定dtype
a = np.array([1, 2, 3], dtype=np.int8)
# 或a = np.array([1, 2, 3], dtype='i1')
print(a.dtype)
# int8
  1. 使用ndarray.astype修改dtype
a = np.array([1, 2, 3])
print(a.dtype) # int32
b = a.astype(np.int8)
print(b.dtype) # int8
  1. 可以使用ndarray.itemsize获取数组中每个元素的大小,单位是字节
a = np.array([1, 2, 3], dtype=np.int32)
print(a.itemsize) # 4

ndarray.size

获取数组中总的元素的个数:

a = np.array([[1, 2, 3], [4, 5, 6], [7, 8, 9]])
print(a.size) # 9

ndarray.ndim

数组的维度:

a = np.array([1, 2, 3])
print(a.ndim) # 1
a = np.array([[1, 2, 3], [4, 5, 6]])
print(a.ndim) # 2
a = np.array([[[1, 2, 3], [4, 5, 6]], [[7, 8, 9], [10, 11, 12]]])
print(a.ndim) # 3

ndarray.shape

数组的维度的元组:

a1 = np.array([1, 2, 3])
print(a1.shape)  # (3,) 一维数组1x3
a2 = np.array([[1, 2, 3], [4, 5, 6]])
print(a2.shape)  # (2, 3) 二维数据2x3
a3 = np.array([[[1, 2, 3], [4, 5, 6]], [[7, 8, 9], [10, 11, 12]]])
print(a3.shape)  # (2, 2, 3) 三维数组2x2x3

可以通过ndarray.reshape来重新修改数组的维度:

a4 = a3.reshape(2, 6)
print(a4)
# [[ 1  2  3  4  5  6]
#  [ 7  8  9 10 11 12]]

Numpy数组操作

索引和切片

  1. 获取某行的数据
a = np.arange(0, 16).reshape((4, 4))
print(a)
# [[ 0  1  2  3]
#  [ 4  5  6  7]
#  [ 8  9 10 11]
#  [12 13 14 15]]
print(a[1])# 获取下标为1的行的数据
# [4 5 6 7]
print(a[-1])# 可以使用负数索引
# [12 13 14 15]
  1. 获取几行的数据
a = np.arange(0, 16).reshape((4, 4))
print(a[0:2])# 获取0至1行数据
print(a[[0,2]])# 获取不连续行的数据
  1. 获取某行某列的数据
a = np.arange(0, 16).reshape((4, 4))
print(a[1, 1])# 获取1行1列的数据
# 5
print(a[0: 2, 0: 2])# 获取0-1行的0-1列数据
# [[0 1]
# [4 5]]
print(a[[0, 2], [0, 2]])# 获取(0,0),(2,2)的两个数据,也叫花式索引
# [0 10]
  1. 获取某列的数据
a = np.arange(0, 16).reshape((4, 4))
print(a[:, 1])# 获取下标为1的列的数据
# [ 1  5  9 13]

布尔索引

a = np.arange(0, 16).reshape((4, 4))
print(a < 10)# 返回一个元素类型为bool的数组
# [[ True  True  True  True]
#  [ True  True  True  True]
#  [ True  True False False]
#  [False False False False]]

如果需要将a中的小于10的元素提取出来:

a = np.arange(0, 16).reshape((4, 4))
print(a[a < 10])
# [0 1 2 3 4 5 6 7 8 9]

其中布尔运算可以有!=,==,<,>,<=,>=以及&(与),|(或)

a = np.arange(0, 16).reshape((4, 4))
print(a[(a < 10) & (a > 5)])
# [6 7 8 9]

值的替换

  1. 利用索引,将指定位置的值替换成其他值
a = np.arange(0, 16).reshape((4, 4))
a[2] = 0 # 将第3行所有值都替换成0
a[3] = np.array([1, 1, 1, 1]) # 将第3行的所有值替换成[1,1,1,1]
print(a)
# [[0 1 2 3]
#  [4 5 6 7]
#  [0 0 0 0]
#  [1 1 1 1]]
  1. 利用条件索引来替换
a = np.arange(0, 16).reshape((4, 4))
a[a < 5] = 0
print(a)
# [[ 0  0  0  0]
#  [ 0  0  0  0]
#  [ 8  9 10 11]
#  [12 13 14 15]]
  1. 利用where函数来实现
a = np.arange(0, 16).reshape((4, 4))
b = np.where(a < 8, 1, 0)  # 把所有小于8的变成1,其余的变成0
print(b)
# [[1 1 1 1]
#  [1 1 1 1]
#  [0 0 0 0]
#  [0 0 0 0]]

案例分析:
取出四阶矩阵对角线元素,分别以一维和二维数组的形式。

a=np.arange(0,16).reshape(4,4)
print(a[np.eye(4)==1])
# [ 1  6 11 16]
a[np.eye(4)==0]=0
print(a)
# [[ 1  0  0  0]
#  [ 0  6  0  0]
#  [ 0  0 11  0]
#  [ 0  0  0 16]]

数组的计算(广播机制)

1.数组与数的计算,加减乘除类似

a=np.random.random((3,4))
a1=a*10 # a的所有元素乘10
a2=a.round(2) # 使所有元素保留两位小数

2.数组与数组的运算
1)结构相同的数据之间的计算

a1 = np.arange(0, 4).reshape(2, 2)
a2 = np.eye(2) * 10
a3 = a1 + a2
print(a3)
# [[10.  1.]
#  [ 2. 13.]]

2)与列数相同并且只有1行的数组之间的计算:会将每个数分别加到每列。

a1 = np.arange(0, 4).reshape(2, 2)
a2 = np.array([0, 10])
a3 = a1 + a2
print(a3)
# [[ 0 11]
#  [ 2 13]]

3)与行数相同并且只有1列的数组之间的计算:会将每个数分别加到每行。

a1 = np.arange(0, 4).reshape(2, 2)
a2 = np.array([[0], [10]])
a3 = a1 + a2
print(a3)
# [[ 0  1]
#  [12 13]]

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

  • shape为(3,8,2)的数组能和(8,1)的数组进行运算吗?
    能,2和1虽然不相等,但有一方为1,所以能。
  • shape为(3,1,4)的数组能和(8,1)的数组进行运算吗?
    能,4和1虽然不相等,且1和8不相等,但两项中有一方为1,所以能。

数组形状的操作

reshape和resize方法

1)reshape是返回数组转换成指定形状后的结果,原数组没有发生改变

a = np.random.randint(0, 10, size=(3, 4))
a1 = a.reshape((2, 6))

2)resize是将数组转换成指定形状,会直接修改原数组,不返回任何值

a = np.random.randint(0, 10, size=(3, 4))
a.resize((2, 6))
flatten和ravel方法

都是将多维数组转换为一维数组。
1)flatten是将数组转换为一维数组后,然后将这个拷贝返回回去,所以后续对这个返回值进行修改不会影响之前的数组。
2)ravel是将数组转换为一维数组后,将这个视图(可以理解为引用)返回回去,所以后续对这个返回值进行修改会影响之前的数组。

a = np.arange(0, 12).reshape(3, 4)
a.flatten()[0] = 100  # 此时a[0]位置的元素还是0
a.ravel()[0] = 100  # 此时a[0]位置的元素是100
不同数组的组合
  1. vstack:将数组按垂直方向进行叠加。数组的列数必须相同才能叠加。
a1 = np.random.randint(0, 10, size=(3, 5))
a2 = np.random.randint(0, 10, size=(1, 5))
a3 = np.vstack([a1, a2])
  1. hstack:将数组按水平方向进行叠加。数组的行必须相同才能叠加。
a1 = np.random.randint(0, 10, size=(3, 2))
a2 = np.random.randint(0, 10, size=(3, 1))
a3 = np.hstack([a1, a2])
  1. concatenate([],axis):将两个数组进行叠加,但是具体是按水平方向还是按垂直方向。则要看axis的参数,如果axis=0,那么代表的是往垂直方向(行)叠加,如果axis=1,那么代表的是往水平方向(列)上叠加,如果axis=None,那么会将两个数组组合成一个一维数组。
a = np.array([[1, 2], [3, 4]])
b = np.array([[5, 6]])
c1=np.concatenate((a, b), axis=0)
print(c1)
# [[1 2]
#  [3 4]
#  [5 6]]
c2=np.concatenate((a, b.T), axis=1)
print(c2)
# [[1 2 5]
#  [3 4 6]]
c3=np.concatenate((a, b), axis=None)
print(c3)
# [1 2 3 4 5 6]

数组的切割

  1. hsplit:按照水平方向进行切割。用于指定分割成几列,可以使用数字来代表分成几部分,也可以使用数组来代表分割的地方。
a = np.arange(0, 8).reshape(2, 4)
b = np.hsplit(a, 2)  # 分割成两部分
print(b)
# [array([[0, 1],
#        [4, 5]]), 
#  array([[2, 3],
#        [6, 7]])]
c = np.hsplit(a, [1, 2])#代表在下标为1和2的地方分别切一刀,分成三部分
print(c)
# [array([[0],
#        [4]]), 
#  array([[1],
#        [5]]), 
#  array([[2, 3],
#        [6, 7]])]
  1. vsplit:按照垂直方向进行切割。用于指定分割成几行,可以使用数字来代表分成几部分,也可以使用数组来代表分割的地方。
a = np.arange(0, 16).reshape(4, 4)
b = np.vsplit(a, 2)  # 分割成两部分
print(b)
# [array([[0, 1, 2, 3],
#        [4, 5, 6, 7]]), 
#  array([[ 8,  9, 10, 11],
#        [12, 13, 14, 15]])]
c = np.vsplit(a, [1, 2])
print(c)
# [array([[0, 1, 2, 3]]), 
#  array([[4, 5, 6, 7]]), 
#  array([[ 8,  9, 10, 11],
#        [12, 13, 14, 15]])]
  1. split/array_split(array,indicate_or_seciont,axis):用于指定切割方式,在切割的时候需要指定是按照行还是按照列,axis=1代表按照列,axis=0代表按照行。
a = np.arange(0, 16).reshape(4, 4)
b = np.array_split(a, 2, axis=0)
print(b)
# [array([[0, 1, 2, 3],
#        [4, 5, 6, 7]]), 
#  array([[ 8,  9, 10, 11],
#        [12, 13, 14, 15]])]

数组(矩阵)转置

  1. 通过ndarray.T返回这个数组的转置的结果。
a = np.arange(0, 6).reshape((2, 3))
print(a.T)
# [[0 3]
#  [1 4]
#  [2 5]]
  1. 通过transpose方法,这个方法返回的是一个View,即修改返回值,会影响到原来数组。
a = np.arange(0, 6).reshape((2, 3))
b = a.transpose()
print(b)
# [[0 3]
#  [1 4]
#  [2 5]]

文件操作

文件保存

可以使用np.savetxt来将数组等保存到文件中。

np.savetxt(frame, array, fmt=’%.18e’, delimiter=None)

  • frame : 文件、字符串或产生器,可以是.gz或.bz2的压缩文件
  • array : 存入文件的数组
  • fmt : 写入文件的格式,例如:%d %.2f %.18e
  • delimiter : 分割字符串,默认是任何空格
a = np.arange(100).reshape(5, 20)
np.savetxt("a.csv", a, fmt="%d", delimiter=",")

文件读取

可以使用np.loadtxt来将数组等从文件中读取。

np.loadtxt(frame, dtype=np.float, delimiter=None, unpack=False)

  • frame:文件、字符串或产生器,可以是.gz或.bz2的压缩文件。
  • dtype:数据类型,可选。
  • delimiter:分割字符串,默认是任何空格。
  • skiprows:跳过前面x行。
  • usecols:读取指定的列,用元组组合。
  • unpack:如果True,读取出来的数组是转置后的。
b=np.loadtxt("a.csv",dtype=np.int16,delimiter=',',skiprows=1,usecols=(1,2,3),unpack=False)

通用函数

一元函数

函数描述
np.abs绝对值
np.sqrt开根
np.square平方
np.exp计算指数(e^x)
np.log,np.log10,np.log2,np.log1p求以e为底,以10为低,以2为低,以(1+x)为底的对数
np.sign将数组中的值标签化,大于0的变成1,等于0的变成0,小于0的变成-1
np.ceil朝着无穷大的方向取整,比如5.1会变成6,-6.3会变成-6
np.floor朝着负无穷大方向取证,比如5.1会变成5,-6.3会变成-7
np.rint,np.round返回四舍五入后的值
np.modf将整数和小数分隔开来形成两个数组
np.isnan判断是否是nan
np.isinf判断是否是inf
np.cos,np.cosh,np.sin,np.sinh,np.tan,np.tanh三角函数
np.arccos,np.arcsin,np.arctan反三角函数

二元函数

函数描述
np.add加法运算,相当于+
np.subtract减法运算,相当于-
np.negative负数运算,相当于加个负号
np.multiply乘法运算,相当于*
np.divide除法运算,相当于/
np.floor_divide取整运算,相当于//
np.mod取余运算,相当于%
greater,greater_equal,less,less_equal,equal,not_equal>,>=,<,<=,=,!=的函数表达式
logical_and&的函数表达式
logical_or\的函数表达式

聚合函数

函数名称NAN安全版本描述
np.sumnp.nansum计算元素的和
np.prodnp.nanprod计算元素的积
np.meannp.nanmean计算元素的平均值
np.stdnp.nanstd计算元素的标准差
np.varnp.nanvar计算元素的方差
np.minnp.nanmin计算元素的最小值
np.maxnp.nanmax计算元素的最大值
np.argminnp.nanargmin找出最小值的索引
np.argmaxnp.nanargmax找出最大值的索引
np.mediannp.nanmedian计算元素的中位数

在使用的时候,可以指定具体哪个轴axis.

布尔数组的函数

函数描述
np.any验证任何一个元素是否为真
np.all验证所有元素是否为真

比如想看下数组中是不是所有元素都为0,那么可以通过以下代码来实现:

np.all(a==0) 
# 或者是
(a==0).all()

比如我们想要看数组中是否有等于0的数,那么可以通过以下代码来实现:

np.any(a==0)
# 或者是
(a==0).any()

排序

  1. np.sort:指定轴进行排序。默认是使用数组的最后一个轴进行排序。还有ndarray.sort(),这个方法会直接影响到原来的数组,而不是返回一个新的排序后的数组。
 a = np.random.randint(0,10,size=(3,5))
 b = np.sort(a) #按照行进行排序,因为最后一个轴是1,那么就是将最里面的元素进行排序。
 c = np.sort(a,axis=0) #按照列进行排序,因为指定了axis=0
  1. np.argsort:返回排序后的下标值。示例代码如下:
 np.argsort(a) #默认也是使用最后的一个轴来进行排序。
  1. 降序排序:np.sort默认会采用升序排序。如果我们想采用降序排序。那么可以采用以下方案来实现:
 # 1. 使用负号
 -np.sort(-a)

 # 2. 使用sort和argsort以及take
 indexes = np.argsort(-a) #排序后的结果就是降序的
 np.take(a,indexes) #从a中根据下标提取相应的元素

其他函数补充:

  1. np.apply_along_axis:沿着某个轴执行指定的函数。示例代码如下:
# 求数组a按行求均值,并且要去掉最大值和最小值。
 np.apply_along_axis(lambda x:x[(x != x.max()) & (x != x.min())].mean(),axis=1,arr=a)
  1. np.linspace:用来将指定区间内的值平均分成多少份。示例代码如下:
 # 将0-1分成12分,生成一个数组
 np.linspace(0,1,12)
  1. np.unique:返回数组中的唯一值。
# 返回数组a中的唯一值,并且会返回每个唯一值出现的次数。
 np.unique(a,return_counts=True)

其他

Axis理解

通常可以理解为axis=0代表的是行,axis=1代表的是列。
具体来说,最外面的括号代表着 axis=0,依次往里的括号对应的 axis 的计数就依次加 1。如图
在这里插入图片描述
操作方式:如果指定轴进行相关的操作,那么他会使用轴下的每个直接子元素的第0个,第1个,第2个…分别进行相关的操作。

x = np.array([[0,1],[2,3]])
# 求x数组在axis=0和axis=1两种情况下的和:
print(x.sum(axis=0))
# [2, 4]
print(x.sum(axis=1))
# [1, 5]

三维以上的数组:
在这里插入图片描述

如果以上数组按照axis=0的方式进行相加,得到的结果如下:
在这里插入图片描述
如果是按照axis=1的方式进行相加,得到的结果如下:
在这里插入图片描述

数据缺失处理

NAN和INF值:

  • NAN:Not A Number,不是一个数字,但属于浮点类型。
  • INF:Infinity,无穷大,属于浮点类型,一般在除数为0时出现。
    注意:NAN和NAN不相等。比如np.NAN != np.NAN这个条件是成立的。
    NAN和任何值做运算,结果都是NAN。

删除缺失值

  1. 删除所有NAN的值,因为删除了值后数组将不知道该怎么变化,所以会被变成一维数组
data = np.random.randint(0, 10, size=(2, 3)).astype(np.float)
data[0, 1] = np.nan
data = data[~np.isnan(data)]  # 此时的data会没有nan,并且变成一个1维数组
print(data)
  1. 删除NAN所在的行
data = np.random.randint(0, 10, size=(3, 5)).astype(np.float)
# 将第(0,1)和(1,2)两个值设置为NAN
data[[0, 1], [1, 2]] = np.NAN
# 获取哪些行有NAN
lines = np.where(np.isnan(data))[0]
# 使用delete方法删除指定的行,axis=0表示删除行,lines表示删除的行号
data1 = np.delete(data, lines, axis=0)

用其他值进行替换

scores = np.loadtxt("nan_scores.csv",skiprows=1,delimiter=",",encoding="utf-8",dtype=np.str)
scores[scores == ""] = np.NAN
scores = scores.astype(np.float)
scores2 = scores.copy()
for x in range(scores2.shape[1]):
    score = scores2[:, x]
    non_nan_score = score[score == score]
    score[score != score] = non_nan_score.mean()
print(scores2.mean(axis=0))
  • 3
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值