如何用uproot读取ROOT文件分支的第i个元素?
使用Uproot高效读取单个波形数据
你当前使用Uproot读取ROOT文件的代码如下:
ifile = uproot.open(path_to_root_file) metadata = ifile['Metadata'] waveforms = ifile['Waveforms'] waveforms.show() waveforms_of_event_50 = waveforms['voltages'].array()[50] print(waveforms_of_event_50)
执行后输出:
name | typename | interpretation ---------------------+--------------------------+------------------------------- event | int32_t | AsDtype('>i4') producer | std::string | AsStrings() voltages | std::vector<std::vect... | AsObjects(AsVector(True, As... [[0.00647, 0.00647, 0.00671, 0.00647, ..., 0.00769, 0.00769, 0.00647], ...]
由于waveforms['voltages']是二维波形数组,直接调用.array()[50]会加载全部数据到内存,导致耗时久甚至内存不足。可以通过以下两种方法实现无需加载全部数据即可获取第i个波形:
方法一:指定条目范围读取
利用array()方法的entry_start和entry_stop参数,只加载目标事件的数据:
ifile = uproot.open(path_to_root_file) waveforms = ifile['Waveforms'] # 仅读取第50个事件(条目从0开始计数) waveforms_of_event_50 = waveforms['voltages'].array(entry_start=50, entry_stop=51)[0] print(waveforms_of_event_50)
entry_start=50和entry_stop=51采用左闭右开的范围规则,只会加载第50个事件的波形数据,取出数组第0个元素即为目标波形。
方法二:通过迭代器逐事件读取
使用iterate()方法生成事件迭代器,遍历到目标条目时提取数据:
ifile = uproot.open(path_to_root_file) waveforms = ifile['Waveforms'] target_entry = 50 waveforms_of_event_50 = None # 逐个遍历事件,找到目标条目后终止循环 for idx, voltage in enumerate(waveforms['voltages'].iterate()): if idx == target_entry: waveforms_of_event_50 = voltage[0] break print(waveforms_of_event_50)
iterate()每次仅加载单个事件的数据,遍历到目标条目后立即退出循环,避免不必要的内存占用。
这两种方法都能大幅降低内存消耗,提升大文件的处理效率。
内容的提问来源于stack exchange,提问作者user171780
相关产品推荐
相关产品推荐

