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

如何用Uproot将Pandas数据框填充的ROOT TH3F直方图写入ROOT文件?

问题:用Pandas数据框填充TH3F并通过Uproot保存到ROOT文件时出现段错误

在Jupyter Notebook中使用Pandas数据框填充ROOT的TH3F直方图,尝试用Uproot以recreate模式写入ROOT文件时出现段错误,代码如下:

import ROOT as R
import uproot as ur
import numpy as np
import pandas as pd

# Example dataframe
data = {
'x': [9.5, 5.0, 2.2, 8.1, 5.5, 1.4, 2.5, 9.2, 3.0, 7.9],
'y': [2.0, 5.7, 1.3, 9.1, 6.0, 6.2, 5.8, 1.8, 5.8, 3.1],
'z': [7.5, 4.1, 3.1, 1.6, 2.4, 8.2, 1.3, 4.4, 2.3, 5.0]
}
df = pd.DataFrame(data)

# Fill TH3F
xyz_hist = R.TH3F('xyz', 'xyz', 100, 0, 10, 100, 0, 10, 100, 0, 10)
for index, row in df.iterrows():
     xyz_hist.Fill(row['x'], row['y'], row['z'])

# Open file and write histogram
outfile = ur.recreate('outfile.root')
outfile['xyz'] = xyz_hist

错误原因

Uproot的recreate接口仅支持写入Uproot原生的直方图对象(如uproot.hist.Histogram3D),而非ROOT的C++ TH3F对象。直接将ROOT的C++对象传入Uproot的文件写入操作会导致内存管理冲突,从而触发段错误。

正确实现方式

方式一:纯ROOT实现(推荐如果依赖ROOT的直方图功能)

直接使用ROOT的API完成直方图填充和文件写入,无需混用Uproot:

import ROOT as R
import pandas as pd

# 示例数据框
data = {
    'x': [9.5, 5.0, 2.2, 8.1, 5.5, 1.4, 2.5, 9.2, 3.0, 7.9],
    'y': [2.0, 5.7, 1.3, 9.1, 6.0, 6.2, 5.8, 1.8, 5.8, 3.1],
    'z': [7.5, 4.1, 3.1, 1.6, 2.4, 8.2, 1.3, 4.4, 2.3, 5.0]
}
df = pd.DataFrame(data)

# 创建TH3F直方图
xyz_hist = R.TH3F('xyz', 'xyz', 100, 0, 10, 100, 0, 10, 100, 0, 10)

# 批量填充数据(*比逐行循环效率更高*)
xyz_hist.FillN(len(df), df['x'].values, df['y'].values, df['z'].values, None)

# 写入ROOT文件
outfile = R.TFile('outfile_root.root', 'RECREATE')
xyz_hist.Write()
outfile.Close()

方式二:纯Uproot实现(推荐Python生态下的高效处理)

直接使用Uproot和NumPy创建并填充3D直方图,避免依赖ROOT的C++对象:

import uproot as ur
import pandas as pd
import numpy as np

# 示例数据框
data = {
    'x': [9.5, 5.0, 2.2, 8.1, 5.5, 1.4, 2.5, 9.2, 3.0, 7.9],
    'y': [2.0, 5.7, 1.3, 9.1, 6.0, 6.2, 5.8, 1.8, 5.8, 3.1],
    'z': [7.5, 4.1, 3.1, 1.6, 2.4, 8.2, 1.3, 4.4, 2.3, 5.0]
}
df = pd.DataFrame(data)

# 定义分箱参数(100个分箱,范围0-10)
bins_x = np.linspace(0, 10, 101)
bins_y = np.linspace(0, 10, 101)
bins_z = np.linspace(0, 10, 101)

# 用NumPy计算3D直方图的频数
counts, edges = np.histogramdd((df['x'], df['y'], df['z']), bins=(bins_x, bins_y, bins_z))

# 创建Uproot原生3D直方图并写入文件
xyz_hist = ur.hist.Histogram3D(edges[0], edges[1], edges[2], counts)
with ur.recreate('outfile_uproot.root') as outfile:
    outfile['xyz'] = xyz_hist

总结

不要混用ROOT的C++直方图对象和Uproot的文件写入接口,选择其中一套工具链完成操作即可:

  • 若需要使用ROOT的高级直方图功能(如拟合、特殊绘制),优先用纯ROOT实现;
  • 若追求Python生态下的高效性和兼容性,优先用纯Uproot实现。

内容的提问来源于stack exchange,提问作者Francesca Kukral

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.30 02:30:36