Python 导入变量时为何只得到最后一个 NumPy 数组?
数据小许
每次循环都会重新给 xyzfile 赋值。循环结束后,它只指向最后生成的数组。from xyzrfile import xyzfile 导入的是该变量当时的值,不会收集它在循环中指向过的所有数组。
可以用字典保存结果,以输入文件名作为键。这样可以分别访问两个数组,也方便为每个数组生成独立文件。
为什么能打印两个形状,却只能导入一个数组?
假设赋值和打印语句都在 for 循环内部,原代码的执行过程是:
- 处理第一个文件,将形状为
(618, 4)的数组赋给xyzfile,然后打印形状。 - 处理第二个文件,将形状为
(1527, 4)的数组赋给同一个变量,再次打印形状。 - 循环结束后,
xyzfile保留第二次赋值的结果。
打印两次说明循环中产生过两个结果,但这个变量只保留了最后一个数组。
提问中贴出的代码缺少循环体缩进。如果实际代码也没有缩进,会先出现 IndentationError;以下示例给出了完整缩进。
在 xyzrfile.py 中用字典收集数组
将读取逻辑封装成函数,由调用方指定输入目录:
# xyzrfile.py
from pathlib import Path
import numpy as np
def load_xyzfiles(folder):
xyzfiles = {}
for path in sorted(Path(folder).glob("*.npz")):
with np.load(path) as data:
coord = data["coordinates"].reshape(-1, 3)
radii = np.full((len(coord), 1), 1.5)
xyzfile = np.concatenate((coord, radii), axis=1)
xyzfiles[path.stem] = xyzfile
return xyzfiles
这里的 xyzfile 仍在每轮循环中重新赋值,同时每个数组都会存入 xyzfiles 字典。对于题目中的文件,字典键分别是 1b7fH.ag 和 1asyH.ag。
np.full((len(coord), 1), 1.5) 直接创建一列半径数据,对应原代码中创建、重复并扩展 radius 的操作。
在另一个脚本中读取并分别保存
假设调用脚本与 pocket_files 文件夹位于同一目录:
# export_xyzr.py
from pathlib import Path
import numpy as np
from xyzrfile import load_xyzfiles
base_dir = Path(__file__).resolve().parent
xyzfiles = load_xyzfiles(base_dir / "pocket_files")
# 根据输入文件名访问对应数组
first_array = xyzfiles["1b7fH.ag"]
second_array = xyzfiles["1asyH.ag"]
print(first_array.shape)
print(second_array.shape)
# 为每个数组保存一个独立文件
output_dir = base_dir / "xyzr_output"
output_dir.mkdir(parents=True, exist_ok=True)
for name, array in xyzfiles.items():
np.save(output_dir / f"{name}_xyzr.npy", array)
如果输入数据与问题描述一致,两个形状应分别为 (618, 4) 和 (1527, 4)。保存后的文件为:
xyzr_output/
1b7fH.ag_xyzr.npy
1asyH.ag_xyzr.npy
之后可以单独加载其中一个数组:
array = np.load(output_dir / "1b7fH.ag_xyzr.npy")
使用时需要注意什么?
- 示例沿用原代码的前提:每个
.npz文件都包含coordinates,且该数据能够按预期整理为三列。reshape(-1, 3)只改变形状,不会从多列数据中自动挑选三列;如果需要筛选坐标列,应根据实际数据结构使用索引。 - 使用路径参数后,无需调用
os.chdir()。导入模块时不会自动遍历输入目录,只有调用load_xyzfiles()才会读取文件。 .npy用于保存单个 NumPy 数组。再次导出到相同路径时,np.save()会覆盖已有文件。- 字典键来自文件名,可以按文件区分结果,无需动态创建
xyzfile1、xyzfile2等变量。
备注:内容仅供参考。
