盘一盘 Python 系列 2 - NumPy (上)(二)

简介: 盘一盘 Python 系列 2 - NumPy (上)(二)

本文首发于“生信补给站”公众号 https://mp.weixin.qq.com/s/HI92_O9uUiFgo_Gl_H6EXw


1.3 数组性质



还记得 Python 里面「万物皆对象」么?numpy 数组也不例外,那么我们来看看数组有什么属性 (attributes) 和方法 (methods)。



一维数组


用按步就班的 np.array() 带列表生成数组 arr



arr = np.array([3.5, 5, 2, 8, 4.2])arr


现在你应该会用 dir(arr) 来查看数组的属性了吧,看完之后我们对 type, ndim, len(), size, shape, stride, dtype 几个感兴趣,一把梭打印出来看看:



print( 'The type is', type(arr) )print( 'The dimension is', arr.ndim )print( 'The length of array is', len(arr) )print( 'The number of elements is', arr.size )print( 'The shape of array is', arr.shape )print( 'The stride of array is', arr.strides )print( 'The type of elements is', arr.dtype )
The type is <class 'numpy.ndarray'>
The dimension is 1
The length of array is 5
The number of elements is 5
The shape of array is (5,)
The stride of array is (8,)
The type of elements is float64


根据结果我们来看看上面属性到底是啥:


  • type数组类型,当然是 numpy.ndarray
  • ndim维度个数是 1
  • len()数组长度为 5 (注意这个说法只对一维数组有意义)
  • size数组元素个数为 5
  • shape数组形状,即每个维度的元素个数 (用元组来表示),只有一维,元素个数为 5,写成元组形式是 (5,)
  • strides跨度即在某一维度下为了获取到下一个元素需要「跨过」的字节数 (用元组来表示),float64 是 8 个字节数 (bytes),因此跨度为 8
  • dtype数组元素类型,是双精度浮点 (注意和 type 区分)


注意我黄色高亮了 strides,这个概念对于解决引言的「转置高维数组」问题很重要。一图胜千言。



咦,为什么有个 Python View 和 Memory Block 啊?这两个不是一样的么?对一维数组来说,「Python 视图」看它和「内存块」存储它的形式是一样的,但对二维数组甚至高维数组呢?




二维数组


还是用按步就班的 np.array() 带二维列表生成二维数组 arr2d



l2 = [[1, 2, 3], [4, 5, 6]]arr2d = np.array(l2)arr2d
array([[1, 2, 3],
       [4, 5, 6]])


一把梭打印属性出来看看:


print( 'The type is', type(arr2d) )print( 'The dimension is', arr2d.ndim )print( 'The length of array is', len(arr2d) )print( 'The number of elements is', arr2d.size )print( 'The shape of array is', arr2d.shape )print( 'The stride of array is', arr2d.strides )print( 'The type of elements is', arr2d.dtype )
The type is <class 'numpy.ndarray'>
The dimension is 2
The length of array is 2
The number of elements is 6
The shape of array is (2, 3)
The stride of array is (12, 4)
The type of elements is int32


同样,我们来分析一下上面属性:


  • type数组类型 numpy.ndarray
  • ndim维度个数是 2
  • len()数组长度为 2 (严格定义 len 是数组在「轴 0」的元素个数)
  • size数组元素个数为 6
  • shape数组形状 (2, 3)
  • strides跨度 (12, 4) 看完下图再解释
  • dtype数组元素类型 int32


对于二维数组,Python 视图」看它和「内存块」存储它的形式是不一样的,如下图所示:



numpy 数组中,默认的是行主序 (row-major order),意思就是每行的元素在内存块中彼此相邻,而列主序 (column-major order) 就是每列的元素在内存块中彼此相邻。


回顾跨度 (stride) 的定义,即在某一维度下为了获取到下一个元素需要「跨过」的字节数。注:每一个 int32 元素是 4 个字节数。对着上图:


  • 第一维度 (轴 0):沿着它获取下一个元素需要跨过 3 个元素,即 12 = 3×4 个字节
  • 第二维度 (轴 1):沿着它获取下一个元素需要跨过 1 个元素,即 4 = 1×4 个字节


因此该二维数组的跨度为 (12, 4)。



n 维数组


用 np.random.random() 来生成一个多维数组:


arr4d = np.random.random( (2,2,2,3) )


里面具体元素是什么不重要,一把梭 arr4d 的属性比较重要:



print( 'The type is', type(arr4d) )print( 'The dimension is', arr4d.ndim )print( 'The length of array is', len(arr4d) )print( 'The number of elements is', arr4d.size )print( 'The shape of array is', arr4d.shape )print( 'The stride of array is', arr4d.strides )print( 'The type of elements is', arr4d.dtype )
The type is <class 'numpy.ndarray'>
The dimension is 4
The length of array is 2
The number of elements is 24
The shape of array is (2, 2, 2, 3)
The stride of array is (96, 48, 24, 8)
The type of elements is float64


除了 stride,都好理解,请根据下图好好想想为什么 stride 是 (96, 48, 24, 8)?[Hint: 一个 float64 的元素占 8 个字节]



算了还是分析一下吧 (免得掉粉 )。回顾跨度 (stride) 的定义,即在某一维度下为了获取到下一个元素需要「跨过」的字节数。注:每一个 float64 元素是 8 个字节数


  • 第一维度 (轴 0):沿着它获取下一个元素需要跨过 12 个元素,即 96 = 12×8 个字节
  • 第二维度 (轴 1):沿着它获取下一个元素需要跨过 6 个元素,即 48 = 6×8 个字节
  • 第三维度 (轴 2):沿着它获取下一个元素需要跨过 3 个元素,即 24 = 3×8 个字节
  • 第四维度 (轴 3):沿着它获取下一个元素需要跨过 1 个元素,即 8 = 1×8 个字节


因此该四维数组的跨度为 (96, 48,24, 8)。


留一道思考题,strides 和 shape 有什么关系



   strides = (96, 48, 24, 8)

   shape = (2, 2, 2, 3)


总不能每个高维数组都用可视化的方法来算 strides 把。


2数组的存载



本节讲数组的「保存」和「加载」,我知道它们没什么技术含量,但是很重要。假设你已经训练完一个深度神经网络,该网络就是用无数参数来表示的。比如权重都是 numpy 数组,为了下次不用训练而重复使用,将其保存成 .npy 格式或者 .csv 格式是非常重要的。


numpy 自身的 .npy 格式

np.save 函数将 numpy 数组保存为 .npy 格式,具体写法如下:


   np.save( ‘’文件名”,数组 )



arr_disk = np.arange(8)np.save("arr_disk", arr_disk)arr_disk


arr_disk.npy 保存在 Jupyter Notebook 所在的根目录下。要加载它也很简单,用 np.load( "文件名" ) 即可:


np.load("arr_disk.npy")
array([0, 1, 2, 3, 4, 5, 6, 7])


文本 .txt 格式

np.savetxt 函数将 numpy 数组保存为 .txt 格式,具体写法如下:


   np.save( ‘’文件名”,数组 )



arr_text = np.array([[1., 2., 3.], [4., 5., 6.]])np.savetxt("arr_from_text.txt", arr_text)


arr_from_text.txt 保存在 Jupyter Notebook 所在的根目录下,用 Notepad 打开看里面确实存储着 [[1,2,3], [4,5,6]]。



np.loadtxt( "文件名" ) 即可加载该文件


np.loadtxt("arr_from_text.txt")
array([[1., 2., 3.],
       [4., 5., 6.]])


文本 .csv 格式

另外,假设我们已经在 arr_from_csv 的 csv 文件里写进去了 [[1,2,3], [4,5,6]],每行的元素是由「分号 ;」来分隔的,展示如下:



np.genfromtxt( "文件名" ) 即可加载该文件


np.genfromtxt("arr_from_csv.csv")
array([nan, nan])


奇怪的是数组里面都是 nan,原因是没有设定好「分隔符 ;」,那么函数 genfromtxt 读取的两个元素是


  • 1;2;3
  • 4;5;6


它们当然不是数字拉,Numpy 只能用两个 nan (Not a Number) 来代表上面的四不像了。


带上「分隔符 ;」再用 np.genfromtxt( "文件名",分隔符 ) 即可加载该文件


np.genfromtxt("arr_from_csv.csv", delimiter=";")
array([[1., 2., 3.],
       [4., 5., 6.]])
相关文章
|
26天前
|
程序员 开发工具 索引
图解Python numpy基本操作
图解Python numpy基本操作
|
1天前
|
存储 API C语言
Python学习笔记之NumPy模块——超详细(安装、数组创建、正态分布、索引和切片、数组的复制、维度修改、拼接、分割...)-2
Python学习笔记之NumPy模块——超详细(安装、数组创建、正态分布、索引和切片、数组的复制、维度修改、拼接、分割...)
|
1天前
|
BI 测试技术 索引
Python学习笔记之NumPy模块——超详细(安装、数组创建、正态分布、索引和切片、数组的复制、维度修改、拼接、分割...)-1
Python学习笔记之NumPy模块——超详细(安装、数组创建、正态分布、索引和切片、数组的复制、维度修改、拼接、分割...)
|
11天前
|
数据挖掘 数据处理 C语言
18. Python 数据处理之 Numpy
18. Python 数据处理之 Numpy
11 2
|
17天前
|
存储 并行计算 数据挖掘
Python中的NumPy库:科学计算与数据分析的基石
Python中的NumPy库:科学计算与数据分析的基石
68 0
|
19天前
|
存储 索引 Python
python学习——NumPy数值计算基础
NumPy基础知识概览:涉及nan(非数字)和inf(无穷)的概念,nan在文件读取或不适当计算时出现,inf在除0操作中出现。数组操作有深拷贝(a=b.copy())、浅拷贝(a=b[:])和引用(a=b)。创建数组方式多样,如`np.array()`、`np.arange()`等。数据类型转换如`np.float64()`、`np.int8()`。随机数生成包含均匀分布、正态分布等。数组索引和切片支持多维操作。改变数组形状用`reshape()`,展平用`ravel()`和`flatten()`。矩阵运算包括加减乘、转置、逆矩阵等。
34 2
python学习——NumPy数值计算基础
|
24天前
|
Python
python相关库的安装:pandas,numpy,matplotlib,statsmodels
python相关库的安装:pandas,numpy,matplotlib,statsmodels
|
1月前
|
存储 机器学习/深度学习 数据处理
NumPy:从初识到实战,探索Python科学计算的无限可能
NumPy:从初识到实战,探索Python科学计算的无限可能
43 0
|
1月前
|
机器学习/深度学习 存储 算法
Python中的NumPy库:数值计算与科学计算的基石
【2月更文挑战第29天】NumPy是Python科学计算的核心库,专注于高效处理大型多维数组和矩阵。其核心是ndarray对象,提供快速数组操作和数学运算,支持线性代数、随机数生成等功能。NumPy广泛应用于数据处理、科学计算和机器学习,简化了矩阵运算、统计分析和算法实现,是数据科学和AI领域的重要工具。
|
1月前
|
存储 索引 Python
请解释Python中的NumPy库以及它的主要用途。
【2月更文挑战第27天】【2月更文挑战第97篇】请解释Python中的NumPy库以及它的主要用途。