如何解读numpy中ndarray数组的order存储顺序参数?
发布于 作者:苏南大叔 来源:程序如此灵动~

作为目前python
代码中强大又常见的第三方数组类型,ndarray
类型,在创建数组的时候有个order
参数,可以控制元素在内存中的存储顺序。就是说在ndarray
形成的时候,输入的元素的实际位置,受到order
参数的控制,控制其元素的实际摆放位置。

苏南大叔的"程序如此灵动"博客,记录苏南大叔的编程经验内容。本文测试环境:win10
,python@3.11.0
,numpy@1.24.2
。
以前有首歌叫做“都选C”来着吧?其实很适合本文,对于和ndarray
扯上关系的order
参数,选择C
是大概率没有问题的。选择F
大概率是会出一些意外的。
前文回顾
本文内容的正确理解,可能需要您了解如下内容:
- 如何定义一个
ndarray
:https://newsn.net/say/numpy-ndarray.html - 使用
range()
生成一个范围:https://newsn.net/say/ndarray-arange.html ndarray
类型的扁平化:https://newsn.net/say/ndarray-flatten.html- 使用
reshape()
重塑数组形状:https://newsn.net/say/ndarray-reshape.html zeros()
和ones()
生成ndarray
:https://newsn.net/say/numpy-zeros-ones.html
重要结论:order!!!
对于python
的ndarray
,相关选项就一个:fortran_order
!取值是True
或者False
!所以,不论本文中的后续内容如何说明,极有可能的真相就是:就是二分法,是不是按列读取!fortran_order
!
可以把ndarray
保存到.npy
或者.npz
文件里面,就可以看到其描述类似为:
有哪些order?
可用的order
有四个,但是常见的就两个。
参数 | 用途 | 说明 |
---|---|---|
C | 按行读取 | 最常见 |
F | 按列读取 | 相对不常见 |
K | 按内存读取 | -- |
A | 按行或列读取 | 对于python 来说,A就等于C |
使用order
参数的函数有如下几个,默认order
参数都是C
。
numpy.copy()
numpy.ravel()
numpy.flatten()
numpy.reshape()
(无法使用K
)numpy.zeros()
numpy.ones()
- 其它
只有定义numpy.array()
中的order
默认是K
(内存)。
order
不影响ndarray
的视图
order
不影响ndarray
的视图。也就是说,无论order
写的是什么值,最终展现出来的视图(通俗的说,print
出来的数据)都是一样的。只是影响成员在内存中的存放顺序,但是这个对于大多数人来说,是无感的。
下面的代码中(不限于这些),虽然order
设置不同,但是,这些变量的打印值一模一样。
输出:

使用.strides
可以做部分区分
因为实际情况下,order
参数A
效果等于C
,K
效果也很可能等于C
。所以,使用.strides
是可以区分F
的情况出来。
strides
:进展,步法。
正常情况下来说,一个元素占四个字节(也不一定,这里就是举个简单的例子。)
测试代码:
输出:

可以看到:
order | 取值 | 第一维度(行)内存差值 | 第二维度(列)内存差值 |
---|---|---|---|
C/K/A | (16,4) | 4个元素*4个字节=16字节 | 4个字节 |
F | (4,8) | 4个字节 | 8个字节 |
查看内存中的实际排序
可以利用了数据扁平化函数的order='K'
参数来进行查看。[用魔法打败魔法]。
这里可以使用.zeval()
和.flatten()
来实现数据的扁平化,但是不能使用reshape(-1)
,会得到错误提示信息:
参考文章:

测试order='C/K/A'
输出:

测试order='F'
输出:
上面的代码显示:内存中的值是按着一列一列的顺序存储的。

输出:
这个代码显示:虽然中间值b
被转置了,但是内存中的存储顺序依然没有发生改变。
相关文章:

结论
可见,order
参数在定义的时候,没有什么大的影响的。但是对其成员进行读取的时候,根据order
的不同,可能会有不同的结果出现。
更多苏南大叔的python
经验文章,请点击:


