Numpy教程(一)—— ndarray:多维数组对象

发布时间:2023年12月20日

前言

该numpy学习笔记参考了菜鸟教程网、b站up主 孙兴华zz 《孙兴华中文讲python数据分析三部曲》以及《北理-python数据分析与展示》,课本推荐使用《利用python进行数据分析》

  • Numpy简介:

? ? ? ? NumPy(Numerical Python) 是 Python 语言的一个扩展程序库,支持大量的维度数组与矩阵? ? ? ? ? ? 运算,此外也针对数组运算提供大量的数学函数库。

1.数组(array)的介绍

? ? ? ?数组是相同数据类型的集合,多个变量共用一个变量名称,并用下标加以区分

  • 数组和列表

? ? ? ?数组和列表都是表达一组数据的有序结构的数据类型,但列表中的数据类型可以不同,数组中的数据类型必须相同

  • 数组和矩阵

? ? ? ? 矩阵(matrix)是数组(array)的一个分支,很多时候二者是通用的,但建议选择数组,更灵活。一般,二维的array也翻译成矩阵?

一维、二维、三维数组

  • N维数组对象:ndarray?

? ? ? ndarray是一个多维数组对象,由两部分构成:实际的数据以及描述这些数据的元数据(如:维度、类型),

? ? ? ndarray数组一般要求所有元素类型相同(因为一般同一维度中,数据类型基本相同,便于计算),数组下标从0开始

? ? ? 优点:可以省去循环,使一维向量更像单个数据;底层实现通过c语言完成,提升计算速度

# 两种数组相加方式对比

# 利用for循环和列表相加两个数组
def shuzujiafa1(n):
    a = [i**3 for i in range(1,n+1)]
    b = [i**2 for i in range(1,n+1)]
    c = []
    for i in range(n):
        c.append(a[i]+b[i])
    return c
print(shuzujiafa1(3))

# 利用numpy库相加两个数组
import numpy as np
def shuzujiafa2(n):
    a = np.arange(1,n+1) ** 3
    b = np.arange(1,n+1) ** 2
    return a+b
print(shuzujiafa2(3))

2.ndarray对象的属性

属性说明
n.ndim返回ndarray对象的秩,即轴的数量或维度
n.shape返回一个元组,表ndarray对象的形状 (几行几列)
n.size返回ndarray对象中元素的个数
n.dtype返回ndarray对象中所有元素的数据类型
n.itemsize返回ndarray对象中每个元素的大小,以字节为单位

3.数组的创建方式

numpy每一次生成的数组中都要把元素作为浮点数(除了arrange函数),因为在科学计算中会大量用到浮点数?

?3.1 常规创建(从列表、元组等类型创建)

? 语法np.array( 列表 或 元组 或 数组等 ,dtype = xxx)? ?

? ? ? ? ? ? 其中列表可以用 range(a,b)代替,dtype是设置数组内对象的数据类型,默认自动识别

? ? ? ? ? ?

??

?3.2 使用函数创建特定数组

  • ?常规函数?
函数说明
np.ones(shape)

根据shape生成一个全1数组,shape是元组或整数类型

例:np.ones((2,3))一>? 生成两行三列的全为1的元组

np.zeros(shape)根据shape生成一个全0数组,shape是元组或整数类型(同上)
np.full ( shape,value )
根据shape生成一个数组,每个元素值都是value
np.eye(n)
创建一个正方的n*n单位矩阵,对角线为1,其余为0
np.empty(shape)根据shape生成一个空数组(一般用于初始化)

  • like类函数:根据已有数组创建新数组
函数说明

np.ones_like(a)

相当于把shape换成了数组a,根据数组a的形状生成想要的数组

即:数组a的shape就是新数组的shape

np.zeros_like(a)
np.empty_like(a)
np.full_like(a,value)
np.concatenate((a,b))将两个或多个维数相同数组合并成一个新的数组

  • 根据数值范围创建数组
函数说明
np.linspace(start,stop,想要的元素个数,endpoint)

根据起止数据等间距的填充数据,形成数组

endpoint:bool类,最后一个元素是否要包含在数组中

例:np.linspace(1,10,4)一>? 数组:1,4,7,10

np.arange

([start,]? 结束? [,step]

类似 array 和 range 函数的组合

例:np.arange(n)? 一>? 返回ndarray类型,元素从0到n-1

  • 利用random函数生成随机数组

? ? ? ? ?语法:import random

? ? ? ? ? ? ? ? ? ? np.random.randn(shape)? ? ?生成shape型的随机数

? ? ? ? ?额外操作:保留小数位数

? ? ? ? ? ? ? ? ? ? np.round(a,2)?? #变量a,保留两位小数点

?3.3 高维数组的创建

  • 方式一:序列(列表)的嵌套,如下:
a = np.array([[1,2],[3,4]])
b = np.array([[[1,2],[5,6]],
              [[1,2],[3,4]],
              [[1,2], [3,4]]])
print(a.ndim,b.ndim)  # 2 3
print(a.shape,b.shape) # (2, 2) (3, 2, 2)

a中数据是一个包含列表的列表,即双层嵌套,故形成了一个2*2的二维数组

b中数据是一个三层列表的嵌套,故形成了一个 3*2*2 的三维数组(可理解成三个2*2的二维数组)

  • 判断高维列表维数的技巧:1)看array与第一个数字间有几个“ [ ”,就是几维

? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ?? 2)看shape中有几个数就是几维? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ??

  • ?方式二:利用函数创建,为shape传递一个元组
c = np.zeros((3,2,1))
print(c)
print(c.ndim,c.shape) # 3 (3, 2, 1)

4.数组的变换

?4.1 维度的变换

方法说明
arr.reshape(shape)

不改变数组元素,新建一个shape形状的数组,原数组不变

? ? 要求:shape中乘积为元素总个数

arr.resize(shape)同上,但修改原数组
arr.swapaxes(a,b)将数组n个维度中两个维度进行调换
arr.flatten()对数组进行降维,返回折叠后的一维数组,原数组不变

?4.2 元素类型的变换

? ? ? ? ? ?语法:arr.astype(元素数据类型)

? ? ? ? ? ?说明:将数组中元素的类型进行转变,这个操作会新建一个数组,原数组不变

?4.3 数组转化为列表?

? ? ? ? ? ? ?语法:arr.tolist()

? ? ? ? ? ? ?作用:数组中的计算速度更快,占用空间更小;但列表可以存储多种数据类型

import numpy as np
# 维度的变换
a = np.array([[1,2],[1,3],[1,2],[2,3]])
print(a)
print(a.ndim) # dim a = 2
print(a.shape)  # shape a = (4,2)

b = a.reshape((2,4))  # shape b = (2,4)
print(b)
print(b.ndim)   # dim b = 2
print("-" * 30)

# 元素类型的变换
c = np.ones((2,3,4),dtype = np.int32)
print(c)

d = c.astype(np.float32)
print(d)
print("-" * 30)

# 转化为列表
e = a.tolist()
print(e)
print(type(e))

5.数组计算

运算说明备注

a + 1

数组a的所有元素都加1

相当于加一个与a形状一样且全为1的数组

减乘除 同理

a + b

a、b的shape一样

对应元素分别相加

a + b

a是一维数组

b是多维数组

a的这一行,与b的每一行分别相运算

一维数组和多维数组可以运算

要求:在某一维度上shape一样

第三种运算具体图解

上述第三种运算,不同尺寸数组之间什么时候可以运算?—— 广播原则

  • 广播原则

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

?例如:(3,2,3)和(2,3):可以运算,后缘维度都是(3,2)

? ? ? ? ? ? (3,2,2)和(2,1):可以运算,后者后缘维度长度是1

? ? ? ? ? ? (3,2,4)和(1,4):可以运算,最后一个后缘维度相等,倒数第二个后者为1

? ? ? ? ? ? (3,2,4)和(1,2):不能运算,后缘维度不相等,且均不为1

6.数组的索引和切片

?6.1 基础索引

  • 一维数组的索引和切片(与python列表类似

? ? ? ?编号方式:从0开始向右递增;或者从-1开始向左递减

? ? ? ?索引数组名 [ 编号数 ]

? ? ? ?切片数组名 [ 起始编号:终止编号(不含):步长?]

  • 多维数组的索引和切片(以三维数组为例)

? ? ? ? 索引数组名 [ a , b , c?]? ? 每个维度一个索引值,用逗号分割

? ? ? ? 切片:同上,在每个维度上分别切片(方法同一维),中间用逗号隔开

? ? ? ? ? ? ? ? ? ?切片本质上是分别在在轴上进行切片

特殊形式:[ : , 1:3 , ::2?]? ?
?“ :” 表示在这个维度上全部都取
?“1:3” 表示在这个维度上取编号1~编号3的元素
? “ ::2 ” 表示在这个维度上从头取到尾,步长为2

??

  • 注:由于Numpy经常处理大数组,避免每次都复制,所以切片在修改时直接修改了原数组?
import numpy as np
a = np.array(range(12)).reshape(3,2,2)
print(a)
b = a[2:,1:,:] 
print(b)
a[2:,1:,:] = 50 # 修改a中切片的值
print(a) # a数组也跟着发生变化

? ? ? ??我们也可以利用这一点来修改数组的数据,例如:

import numpy as np
arr = np.zeros((4,3),dtype=int)
arr[:] = 5 #相当于切片了所有数据
print(arr)

? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ?

?6.2 布尔索引?

与数学操作类似,数组的比较操作也是可以向量化的,因此比较数组会返回给我们一个bool值数组

直接输入print(条件)即可,也可利用 数组名[ 条件?] = n 来进行赋值

  • 例1:把一维数组进行01化处理(大于5的设为1,小于5的设为0)
import numpy as np
a = np.arange(13)
print(a)
a[a <= 5] = 0
a[a > 5] = 1
print(a) #结果为:[0 0 0 0 0 0 1 1 1 1 1 1 1]

? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ?

  • 例2:找出大于6且为偶数的数,并赋值为0

? ? ? ? python的关键字and 和 or 对布尔数值并没有用,需要使用 & 和 | 来代替

? ? ? ? 另外,~ 符号可以用来对一个条件取反时使用

import numpy as np
a = np.arange(12).reshape(2,6)
print(a)
print("-"*40)
tiaojian = (a%2==0) & (a>5) #条件
print(tiaojian)
a[tiaojian] = 0
print("-"*40)
print(a)

?6.3 神奇索引

神奇索引主要用于描述使用整数数组进行数据索引

import numpy as np
a = np.arange(32).reshape(8,4)
print(a)
print("-"* 30)
print(a[[4,3,0,6]])   # 返回第4行,第3行,第0行,第6行
print("-"* 30)
print(a[[1,5,7,2],[0,3,1,2]])   # 取第1行第0列,第5行第3列,第7行第1列,第2行第2列

  • 案例:获取数组中最大的前N个数字
import numpy as np
a = np.random.randint(1,100,10)
print(a)
xiabiao = a.argsort()[-3:] #argsort()会返回排序后的下标,选取最大的三个
print(xiabiao)
max = a[xiabiao]
print(max)

? ? ? ? ?? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ?

7.数组的轴(axis)

?7.1 轴的介绍

? ? ?在官网中有这样一句话:“?In NumPy dimensions are called axes”,即维度称为轴?

? ? 一般如果维度是二维,我们就可以用x、y轴去描述一个点;如果是三维,就需要再加上z轴

? ? 所以我们可以将二者等价理解? ? ? ? ? ??

轴的简单图解

  • 凡是提到轴,先看数组的维度,有几维就有几个轴? ? ? ?

? ? ??轴的编号 和 切片时我们使用的shape元组的索引是对等的,一条轴其实就是一个维度(层级)

? ? ? 而且轴的方向与索引编号方向一致

? ? ? 例如:shape(3,2,4):分别对应(0轴,1轴,2轴);

? ? ? ? ? ? ? ? ? ?而对具体维度而言,0轴对应三维,1轴对应二维,2轴对应一维

  • 我们经常用到的shape可以理解为在每个轴(axis)上的size

? ? ? ?如下图:axis=0表示第一层(黑色),该层数组的size为3;axis=1表示第二层(红色),该层数组的size为2;axis=2表示第三层(蓝色),对应轴上的元素length = 4。

?

?7.2 numpy转置换轴

? 例:要将data(2,3)转化为(3,2)

?

方法语法说明
reshape(重组)data.reshape(3,2)
transpose(矩阵转置)

data.transpose ( )

也可简写为? data.T

行列转置
swapaxes(轴转置)data.swapaxes(1,0)

该方法参数接收一对轴编号,

并对轴进行调整用于重组数据

? ? ?

文章来源:https://blog.csdn.net/m0_61766362/article/details/134970740
本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。