日拱一卒之Python与matlab的内存读取区别

日拱一卒之Python与matlab的内存读取区别

Python与matlab的内存读取区别

简单来说,​Python (NumPy) 和 Matlab 在 reshape时的核心区别在于"内存读取顺序"不同

  • Python (NumPy): 默认使用 行优先 (Row-Major Order) ,即"先填满第一行,再填第二行..."。
  • Matlab: 默认使用 列优先 (Column-Major Order) ,即"先填满第一列,再填第二列..."。

1. 直观的区别:举个例子

假设我们有一个包含 1 到 6 的一维数组,想要把它转换成一个 2行 3列 的矩阵。

输入数据

1,2,3,4,5,6\] \[1, 2, 3, 4, 5, 6\] \[1,2,3,4,5,6

Python (NumPy) 的做法

Python 会横向填充数据。

Python

复制代码
import numpy as np
a = np.array([1, 2, 3, 4, 5, 6])
b = a.reshape(2, 3)
print(b)

结果:

123456\] \\begin{bmatrix} 1 \& 2 \& 3 \\\\ 4 \& 5 \& 6 \\end{bmatrix} \[142536

特点: 数字 1,2,31, 2, 31,2,3 都在第一行。

Matlab 的做法

Matlab 会纵向填充数据。

Matlab

复制代码
a = 1:6;
b = reshape(a, 2, 3);
disp(b)

结果:

135246\] \\begin{bmatrix} 1 \& 3 \& 5 \\\\ 2 \& 4 \& 6 \\end{bmatrix} \[123456

特点: 数字 1,21, 21,2 都在第一列。


2. 为什么会有这种区别?

这个区别源于两种编程语言的历史背景和底层实现标准。计算机内存是线性的(像一条长纸带),多维数组在内存中必须"拉直"存放。

Matlab (Fortran 流派)
  • 来源: Matlab 最早是作为 LINPACK 和 EISPACK (线性代数库) 的接口编写的,这些库是用 Fortran 语言写的。
  • 标准: Fortran 语言标准规定数组在内存中是 列优先 (Column-Major) 存储的。这意味着内存中相邻的两个地址,对应的是矩阵中同一列上下相邻的两个元素。
  • 逻辑: 在科学计算中,很多线性代数操作是对列向量进行的,列优先存储在某些数学运算上(如访问列向量)效率更高。
Python/NumPy (C 流派)
  • 来源: Python 的解释器以及 NumPy 的底层主要是用 C 语言 编写的。
  • 标准: C 语言标准规定数组是 行优先 (Row-Major) 存储的。这意味着内存中相邻的两个地址,对应的是矩阵中同一行左右相邻的两个元素。
  • 逻辑: 这更符合人类阅读文字的习惯(从左到右,换行)。

3. 如何在 Python 中模仿 Matlab 的行为?

如果你正在将 Matlab 代码移植到 Python,并且希望 reshape​ 的结果与 Matlab 完全一致,你不需要手动转置,只需要修改 NumPy 的 order 参数。

NumPy 的 reshape​ 接受一个 order 参数:

  • 'C' (默认): C-style,即行优先
  • 'F': Fortran-style,即列优先(模仿 Matlab)。

代码示例:

Python

复制代码
import numpy as np

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

# 使用 order='F' 来模拟 Matlab 的行为
b_matlab_style = a.reshape((2, 3), order='F')

print(b_matlab_style)

输出:

Plaintext

复制代码
[[1 3 5]
 [2 4 6]]

在实际的使用中要多注意,这个是非常容易出错的地方。

numpy.fromfile函数的用法

numpy.fromfile​ 是 NumPy 库中一个非常高效的函数,专门用于从文件中读取数据并将其转换为 NumPy 数组。它最常用于读取 纯二进制文件 (Raw Binary Files)

1. 函数签名

python 复制代码
numpy.fromfile(file, dtype=float, count=-1, sep='', offset=0, like=None)

2. 核心参数详解

file (必选):文件路径(字符串)或已打开的文件对象。

dtype​ (关键参数):数据类型 。指定文件中每个数据点占据多少字节以及如何解释这些字节。二进制文件没有"头文件 "来告诉程序数据是什么格式。如果你的文件存的是 16位整数 (int16​),但你默认用 float 读取,读出来的数据全是乱码。

常用值

  • np.int16: 2字节整数(雷达/音频常见)。
  • np.float32: 4字节浮点数。
  • np.complex64: 8字节复数。
  • >f4 / <i2: 指定大小端(Big-endian / Little-endian),如果数据是在不同架构的机器上生成的,这很重要。

count​::要读取的数据项数量(不是字节数,是 dtype​ 指定的元素个数)。默认值-1​,表示读取整个文件直到结束。如果只想读文件的前 1000 个点,设 count=1000

sep​:分隔符。 ''(空字符串,默认)读取二进制文件 。这是该函数最主要的用途。​' '​ 或 ','​:如果指定了分隔符,函数会把它当作文本文件读取(类似于 CSV)。但读文本通常推荐用 np.loadtxt​ 或 pandas​,因为 fromfile 读文本不够灵活且速度优势不明显。

offset​:从文件开头跳过的字节数 。如果文件有一个文件头(Header),比如前 1024 字节是描述信息,真正的数据在后面,你可以设置 offset=1024 来跳过头部直接读数据。

3. 关键注意事项(坑点)

  1. 返回永远是一维数组
    np.fromfile 读取的是字节流,它不知道数据的行和列。它只是把字节挨个读进来排成一排。因此,读取后几乎总是 需要接一个 .reshape() 函数来还原数据的真实维度。
  2. 不包含元数据
    np.load (读取 .npy 文件) 不同,fromfile 读取的二进制文件不包含形状(shape)或数据类型(dtype)信息。必须预先知道 这个文件的格式(比如是 int16 还是 float32,长宽是多少),否则无法正确还原。

整数索引(与切片的不同)

整数索引 (Integer Indexing) 是 NumPy(以及 Python 列表)中最基础但也最重要的概念之一。

简单来说,就是使用一个具体的整数(如 0, 1, -1)来访问数组中的特定位置

什么是整数索引?

它的核心特征是: "选中并提取" 。当对某个维度使用整数索引时,NumPy 会认为:"你想要这个确切位置的数据,这个维度本身对你来说已经没用了。"

后果: 该维度会从结果的形状(shape)中消失(降维)。

直观对比:整数索引 vs 切片 (Slicing)

假设有一个 2D 数组(3行3列):

python 复制代码
import numpy as np
arr = np.array([
    [1, 2, 3],
    [4, 5, 6],
    [7, 8, 9]
])
# 形状是 (3, 3)
操作方式 代码 结果 形状 (Shape) 含义
整数索引 arr[0] [1, 2, 3] (3,) 我要第0行的数据。(维度从2D降为1D,行维度消失了
切片 arr[0:1] [[1, 2, 3]] (1, 3) 我要包含第0行的一个子数组 。(维度保持2D,行维度还在,只是长度为1)

通俗比喻:

  • 切片 (0:1 ) :像是在切面包。即使你切了非常薄的一片,它依然是一片面包(它还是三维物体,只是厚度很小)。
  • 整数索引 (0 ) :像是把那片面包上的图案印在一张纸上。它不再有"厚度"这个概念了,它变成了二维的纸。
相关推荐
此处不留情3 小时前
从零构建智能水果识别系统:数据模块深度解析
人工智能·pytorch
声声codeGrandMaster14 小时前
AI之模型提升
人工智能·pytorch·python·算法·ai
拾贰_C20 小时前
【python | pytorch | scipy】scipy scikit-learn库相互依赖?
pytorch·python·scipy
拾贰_C20 小时前
【python | pytorch | warehouse】python库scipy与scikit-learn库不兼容?
pytorch·python·scipy
andwhataboutit?21 小时前
pytorch-CycleGAN-and-pix2pix学习
人工智能·pytorch·学习
拾贰_C1 天前
【python | pytorch | 】.报错怎么找到问题所在?
开发语言·pytorch·python
wenxiaohai1231 天前
在anaconda中安装cuda-pytorch
人工智能·pytorch·python·anaconda
拾贰_C1 天前
【python| pytorch】卸载py库,手动法
开发语言·pytorch·python