从.root文件读取树,然后将零填充.h5文件

时间:2019-11-22 20:20:28

标签: uproot

我有一个.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],您能否建议在根目录下执行此操作最聪明,最节省内存的方法?

谢谢, 德波。

1 个答案:

答案 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填充每个数组,然后使用Nonefillna的值变为零。在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列,但可能有数百万或数十亿行。