我有一个.root文件,其中包含一个名为FlatSubstructureJetTreeD的树 文件= uproot.open(“ / data / debo / jetAnomaly / AtlasData / dijets / mergedRoot / miniTrees / user.cdelitzs.JZ2W.mini.root”)[“ FlatSubstructureJetTreeD”]
它具有以下分支机构
file.keys() ['fjet_pt', 'fjet_clus_P', 'fjet_clus_px', 'fjet_clus_py', 'fjet_clus_pz', 'EventInfo_mcEventWeight', 'fjet_xsec_filteff_numevents']
fjet_clus_P,fjet_clus_px,fjet_clus_py,fjet_clus_pz是锯齿状数组(不同事件中的不同条目)
我需要以.h5文件的形式制作一个零填充数据集,以便每一行都具有[fjet_clus_P1,fjet_clus_px1,fjet_clus_py1,fjet_clus_pz1,fjet_clus_P2,fjet_clus_px2,fjet_clus_py2,fjet_clus_py ... fjet_clus_Pn,fjet_clus_pxn,fjet_clus_pyn,fjet_clus_pzn],您能否建议在根目录下执行此操作最聪明,最节省内存的方法?
谢谢, 德波。
答案 0 :(得分:0)
假设您已将所有数组作为名为arrays
的字典读出,
import uproot
file = uproot.open("/data/debo/jetAnomaly/AtlasData/dijets/mergedRoot/"
"miniTrees/user.cdelitzs.JZ2W.mini.root"
)["FlatSubstructureJetTreeD"]
arrays = file.arrays(["fjet_clus_P", "fjet_clus_px", "fjet_clus_py",
"fjet_clus_pz"], namedecode="utf-8")
您可以使用None
方法pad
填充每个数组,然后使用None
将fillna
的值变为零。在pad
中,您必须指定一个长度;让我们以每个事件的最大长度为准。完成此操作后,JaggedArrays
在第二维上的长度相等,因此将它们regular
转换为NumPy数组。
for name in arrays:
longest = arrays[name].counts.max()
arrays[name] = arrays[name].pad(longest).fillna(0).regular()
现在它们是(二维)NumPy数组,h5py将识别它们,您可以按常规方式将它们写入HDF5文件。
编辑:并且,如果您希望所有数据都位于连续的块数组中,则必须选择单个longest
长度,预先分配块并填充它。 (对regular
的调用现在应该是可选的,但请检查一下。)
longest = 2
for name in arrays:
arrays[name] = arrays[name].pad(longest).fillna(0)
output = numpy.empty(file.numentries,
dtype=[("px1", "f8"), ("py1", "f8"), ("pz1", "f8"),
("px2", "f8"), ("py2", "f8"), ("pz2", "f8")])
output["px1"] = arrays["fjet_clus_px"][:, 0]
output["py1"] = arrays["fjet_clus_py"][:, 0]
output["py1"] = arrays["fjet_clus_pz"][:, 0]
output["px2"] = arrays["fjet_clus_px"][:, 1]
output["py2"] = arrays["fjet_clus_py"][:, 1]
output["py2"] = arrays["fjet_clus_pz"][:, 1]
这是向量化的(即没有Python用于隐式或显式的循环)。即使您在所有列名上编写了一个循环,也只有10列,但可能有数百万或数十亿行。