You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何在Python3中加速3D矩阵的赋值操作?

Python3加速3D矩阵赋值的优化思路

背景

我使用Python3处理Fortran90输出的3D数据集以实现可视化。Fortran将3D矩阵以2D文本格式输出,每行结构为:

Value,  x, y, z

示例:

123443.0,  1, 1, 1
   123343.0,  1, 1, 2
   134554.0,  1, 1, 3

其中Value是3D矩阵的元素值,x、y、z对应元素在3D矩阵中的位置。我原本的读取和赋值代码如下:

input_path="/user_path/3D_CUBE_data.txt"

#READ DATASET
read_1=np.loadtxt(input_path)
read_2 = pd.DataFrame(read_1, columns=["data","x","y","z"])

print("input_shape=", read_2.shape)

#CREATE A 3D MATRIX
#(dis, tra, rows)
dis = 41
tra = 18
rows = 4096

data_1 = np.zeros( shape = (dis, tra, rows) )


x_l = list(range(1,dis+1))
y_l = list(range(1,tra+1))
z_l = list(range(1,rows+1))

#ASSIGN VALUES IN THE 3D MATRIX
for y in y_l :
   for x in x_l :
       line_1 = read_2[(read_2["x"]==int(x)) & (read_2["y"]==int(y))]

       data_1[x-1,y-1,:] = line_1.loc[:,["data"]].T

我认为嵌套的两层for循环是赋值过程速度慢的主要原因,希望找到加速这个过程的方法。

优化方案

1. 利用NumPy高级索引直接赋值(最推荐)

直接提取x、y、z的0-based索引,一次性将数据值映射到3D矩阵对应位置,完全规避Python循环:

import numpy as np

input_path="/user_path/3D_CUBE_data.txt"

# 读取数据
read_1 = np.loadtxt(input_path, delimiter=",")
# 拆分出数据和索引列
data_vals = read_1[:, 0]
# 转换为0-based索引(原数据是1-based)
x_indices = (read_1[:, 1] - 1).astype(int)
y_indices = (read_1[:, 2] - 1).astype(int)
z_indices = (read_1[:, 3] - 1).astype(int)

# 创建3D矩阵
dis = 41
tra = 18
rows = 4096
data_1 = np.zeros((dis, tra, rows))

# 一次性完成赋值
data_1[x_indices, y_indices, z_indices] = data_vals

该方法依托NumPy底层的C实现,速度比Python循环快数个数量级。

2. 用Pandas分组操作替代嵌套循环

若需保留DataFrame处理流程,可按x、y分组后批量赋值:

import numpy as np
import pandas as pd

input_path="/user_path/3D_CUBE_data.txt"

read_2 = pd.read_csv(input_path, sep=",", header=None, names=["data","x","y","z"], skipinitialspace=True)

dis = 41
tra = 18
rows = 4096
data_1 = np.zeros((dis, tra, rows))

# 按x、y分组后直接赋值
for (x_val, y_val), group in read_2.groupby(["x", "y"]):
    x_idx = int(x_val) - 1
    y_idx = int(y_val) - 1
    # 确保分组内z值是连续有序的(与原文件输出顺序一致)
    data_1[x_idx, y_idx, :] = group["data"].values

分组操作的效率优于嵌套循环,但仍不及纯NumPy索引方案。

3. 优化数据读取步骤

针对大文件,替换np.loadtxt为更高效的读取方法,减少整体运行时间:

# 用Pandas读取,自动处理逗号分隔和空格
read_2 = pd.read_csv(input_path, sep=",", header=None, names=["data","x","y","z"], skipinitialspace=True)

# 或用NumPy的genfromtxt
read_1 = np.genfromtxt(input_path, delimiter=",")

4. 提前指定数据类型

读取时直接指定各列的数据类型,避免后续类型转换开销:

read_1 = np.loadtxt(
    input_path,
    dtype=[('data', 'float64'), ('x', 'int32'), ('y', 'int32'), ('z', 'int32')],
    delimiter=','
)
data_vals = read_1['data']
x_indices = read_1['x'] - 1
y_indices = read_1['y'] - 1
z_indices = read_1['z'] - 1

内容的提问来源于stack exchange,提问作者Changwan Sun

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.18 17:37:31