【问题标题】:efficient way to convert a nested list to numpy array将嵌套列表转换为 numpy 数组的有效方法
【发布时间】:2013-03-08 12:04:46
【问题描述】:

我有一个具有不同列表大小和类型的嵌套列表。

def read(f,tree,objects):

Event=[]
for o in objects:
    #find different features of one class 
    temp=[i.GetName() for i in tree.GetListOfBranches() if i.GetName().startswith(o)]
    tempList=[] #contains one class of objects
    for t in temp:
        #print t
        tempList.append(t)
        comp=np.asarray(getattr(tree,t))
        tempList.append(comp)
Event.append(tempList)

return Event



def main():
    path="path/to/file"
    objects= ['TauJet', 'Jet', 'Electron', 'Muon', 'Photon', 'Tracks', 'ETmis', 'CaloTower']

    f=ROOT.TFile(path)
    tree=f.Get("RecoTree")
    tree.GetEntry(100)
    event=read(f,tree,objects)

例如 event[0] 的结果是

['TauJet', array(1), 'TauJet_E', array([ 31.24074173]), 'TauJet_Px', array([-28.27997971]), 'TauJet_Py', array([-13.18042469]), 'TauJet_Pz', array([-1.08304048]), 'TauJet_Eta', array([-0.03470514]), 'TauJet_Phi', array([-2.70545626]), 'TauJet_PT', array([ 31.20065498]), 'TauJet_Charge', array([ 1.]), 'TauJet_NTracks', array([3]), 'TauJet_EHoverEE', array([ 1745.89221191]), 'TauJet_size', array(1)]

如何将其转换为 numpy 数组?

注意 1:np.asarray(event, "object") 很慢。我正在寻找更好的方法。就我没有固定类型而言,np.fromiter() 也不适用

注意 2:我不知道我的事件的长度。

注意 3:如果它使事情变得更容易,我也可以得到名字。

【问题讨论】:

  • 我建议你看看pandasDataFrames。我记得(希望是正确的)在某处读到对不同长度的列有一些支持。此外它们还支持一些 numpy 算术

标签: python list numpy


【解决方案1】:

您可以尝试这样的事情,但我不确定它会多快。这将为第一行创建一个 numpy 记录数组。

data = event[0]
keys = data[0::2]
vals = data[1::2]
#there are some zero-rank arrays in there, so need to check for those, 
#but I think just recasting them to a np.float should work. 
temp = [np.float(v) for v in vals]
#you could also just create a np array from the line above with np.array(temp)
dtype={"names":keys, "formats":("f4")*len(vals)}
myArr = np.rec.fromarrays(temp, dtype=dtype)

#test it out
In [53]: data["TauJet_Pz"]
Out[53]: array(-1.0830404758453369, dtype=float32)


#alternatively, you could try something like this, which just creates a 2d numpy array
vals = np.array([[np.float(v) for v in row[1::2]] for row in event])
#now create a nice record array from that using the dtypes above
myRecordArray = np.rec.fromarrays(vals, dtype=dtype)

【讨论】:

  • 我无法完成这项工作。正如我所说,我有不同长度的列表。所以当我输入的长度与我在这里提到的不同时,我得到: temp2=[np.float(v) for v in vals] TypeError: only length-1 arrays can be convert to Python scalars and even for this length I get : myArr = np.rec.fromarrays(temp2, dtype=dtype) File "/usr/lib/pymodules/python2.7/numpy/core/records.py", line 537, in fromarrays descr = sb.dtype(dtype) TypeError : 数据类型不理解
  • 听起来行中有多个元素的数组,即类似于 ["TauJet_E", array([31.56, 45.14])]。这将重现您看到的错误。为什么会这样?
  • 我的代码与我在问题中发布的完全一样!正如我所说,当我在做 (comp=np.asarray(getattr(tree,t))) 时,vectore 的长度可能会因一个对象而异。所以例如我可能有:'Jet_E', array([ 391.62017822, 31.24074173]),我使用 v.astype(float) 解决了这个问题,但我仍然有 TypeError 的问题:最后一部分中不理解数据类型
  • 那么当一个粒子有多个值时,单独的值是什么?
  • 例如 Electron_E 的值为 [23,32,23] 意味着我们有三个 Electron,我们的能量为 23,32,23。
猜你喜欢
  • 2018-12-24
  • 2022-06-10
  • 1970-01-01
  • 2012-11-24
  • 1970-01-01
  • 1970-01-01
  • 2023-03-07
  • 2022-12-07
  • 2018-12-06
相关资源
最近更新 更多