Python 在阵列中重塑阵列的形状

Python 在阵列中重塑阵列的形状,python,numpy,dataframe,uproot,awkward-array,Python,Numpy,Dataframe,Uproot,Awkward Array,我有一个根文件,打开时有2000个条目,子条目的数量是可变的,每列中都有一个不同的变量。假设我只对其中的5个感兴趣。我想把它们放在一个数组中,np.shape(array)=(2000250,5)。250足够包含每个条目的所有子条目 根文件通过Outlot DATA=[variablename:[array of entries[array of subentries]]转换为字典 我创建了一个数组np.zeros(2000250,5),并用我想要的数据填充它,但它需要大约500毫秒,我需要一个

我有一个根文件,打开时有2000个条目,子条目的数量是可变的,每列中都有一个不同的变量。假设我只对其中的5个感兴趣。我想把它们放在一个数组中,
np.shape(array)=(2000250,5)
。250足够包含每个条目的所有子条目

根文件通过Outlot DATA=[variablename:[array of entries[array of subentries]]转换为字典

我创建了一个数组
np.zeros(2000250,5)
,并用我想要的数据填充它,但它需要大约500毫秒,我需要一个解决方案,可以在以后的100万个条目中扩展。我找到了多个解决方案,但我的最低值约为300毫秒

lim_i=len(N_DATA["nTrack"])
i=0
INPUT_ARRAY=np.zeros((lim_i,500,5))
for l in range(len(INPUT_ARRAY)):
    while i < lim_i:
        EVENT=np.zeros((500,5))
        k=0
        lim_k=len(TRACK_DATA["Track_pt"][i])
        while k<lim_k:
            EVENT[k][0]=TRACK_DATA["Track_pt"][i][k]
            EVENT[k][1]=TRACK_DATA["Track_phi"][i][k]
            EVENT[k][2]=TRACK_DATA["Track_eta"][i][k]
            EVENT[k][3]=TRACK_DATA["Track_dxy"][i][k]
            EVENT[k][4]=TRACK_DATA["Track_charge"][i][k]
            k+=1
        INPUT_ARRAY[i]=EVENT
        i+=1
INPUT_ARRAY
lim_i=len(N_数据[“nTrack”])
i=0
输入数组=np.0((lim_i,500,5))
对于范围内的l(len(输入_数组)):
当我观察1:我们可以直接分配到
INPUT\u ARRAY[i]
的适当子数组,而不是创建
EVENT
作为
INPUT\u ARRAY[i]
的代理,然后将其复制到中。(我还将使用小写字母设置变量名,以遵循正常惯例)

lim_i = len(n_data["nTrack"])
i = 0
input_array = np.zeros((lim_i,500,5))
for l in range(len(input_array)):
    while i < lim_i:
        k = 0
        lim_k = len(track_data["Track_pt"][i])
        while k < lim_k:
            input_array[i][k][0] = track_data["Track_pt"][i][k]
            input_array[i][k][1] = track_data["Track_phi"][i][k]
            input_array[i][k][2] = track_data["Track_eta"][i][k]
            input_array[i][k][3] = track_data["Track_dxy"][i][k]
            input_array[i][k][4] = track_data["Track_charge"][i][k]
            k += 1
        i += 1
观察3:但是现在,我们最里面的循环的目的只是沿着最后一个维度复制一整块
track_data
。我们可以直接这样做:

track_array = np.dstack((
    track_data['Track_pt'],
    track_data['Track_phi'],
    track_data['Track_eta'],
    track_data['Track_dxy'],
    track_data['Track_charge']
))
lim_i = len(n_data["nTrack"])
i = 0
input_array = np.zeros((lim_i,500,5))
for l in range(len(input_array)):
    while i < lim_i:
        k = 0
        lim_k = len(track_data["Track_pt"][i])
        while k < lim_k:
            input_array[i][k] = track_data[i][k]
            k += 1
        i += 1

注意fKarl Knechtel的第二条评论,“您应该避免自己显式地迭代Numpy数组(实际上可以保证有一个内置的Numpy东西,它只做您想要的,并且可能比本机Python快得多),”有一种方法可以通过一次一个数组的编程实现,但在NumPy中却不行。Outlot返回的原因是您需要一种有效处理可变长度数据的方法

我没有您的文件,但我将从一个类似的文件开始:

>>> import uproot4
>>> import skhep_testdata
>>> events = uproot4.open(skhep_testdata.data_path("uproot-HZZ.root"))["events"]

从该文件开始的分支“MuoNuy”与您的轨道中的长度相同。(C++类型名是一个动态大小的数组,用Python解释为jjigd)。 如果你只是要求这些数组,你会发现它们是一个笨拙的数组

>>> muons = events.arrays(filter_name="Muon_*")
>>> muons
<Array [{Muon_Px: [-52.9, 37.7, ... 0]}] type='2421 * {"Muon_Px": var * float32,...'>
这意味着什么?这意味着您有2421条记录,其中的字段名为
“Muon_Px”
,等等,每个字段都包含可变长度的
float32
int32
,具体取决于字段。我们可以通过将其转换为Python列表和dict来查看其中一条记录

>>> muons[0].tolist()
{'Muon_Px': [-52.89945602416992, 37.7377815246582],
 'Muon_Py': [-11.654671669006348, 0.6934735774993896],
 'Muon_Pz': [-8.16079330444336, -11.307581901550293],
 'Muon_E': [54.77949905395508, 39.401695251464844],
 'Muon_Charge': [1, -1],
 'Muon_Iso': [4.200153350830078, 2.1510612964630127]}
(您可以通过将
how=“zip”
传递给或使用and数组来创建这些记录列表,而不是列表的记录,但这与您想要做的填充是相切的。)

问题是列表的长度不同。NumPy没有任何函数可以帮助我们,因为它完全处理直线数组。因此,我们需要一个特定于数组的函数

你想把这些不规则的列表变成大小相同的规则列表。这叫做“填充”。同样,有一个函数可以实现这一点,但我们首先需要得到元素的最大数量,这样我们就知道填充多少

>>> ak.max(ak.num(muons))
4
所以让我们把它们都做成4号

>>> ak.pad_none(muons, ak.max(ak.num(muons)))
<Array [{Muon_Px: [-52.9, 37.7, ... None]}] type='2421 * {"Muon_Px": var * ?floa...'>
您希望用零填充它们,而不是
None
,因此我们将缺少的值转换为零

>>> ak.fill_none(ak.pad_none(muons, ak.max(ak.num(muons))), 0)[0].tolist()
{'Muon_Px': [-52.89945602416992, 37.7377815246582, 0.0, 0.0],
 'Muon_Py': [-11.654671669006348, 0.6934735774993896, 0.0, 0.0],
 'Muon_Pz': [-8.16079330444336, -11.307581901550293, 0.0, 0.0],
 'Muon_E': [54.77949905395508, 39.401695251464844, 0.0, 0.0],
 'Muon_Charge': [1, -1, 0, 0],
 'Muon_Iso': [4.200153350830078, 2.1510612964630127, 0.0, 0.0]}
最后,NumPy没有记录(除了,这也意味着列在内存中是连续的;笨拙数组的“记录”是抽象的)

>>> arrays = ak.unzip(ak.fill_none(ak.pad_none(muons, ak.max(ak.num(muons))), 0))
>>> arrays
(<Array [[-52.9, 37.7, 0, 0, ... 23.9, 0, 0, 0]] type='2421 * var * float64'>,
 <Array [[-11.7, 0.693, 0, 0, ... 0, 0, 0]] type='2421 * var * float64'>,
 <Array [[-8.16, -11.3, 0, 0, ... 0, 0, 0]] type='2421 * var * float64'>,
 <Array [[54.8, 39.4, 0, 0], ... 69.6, 0, 0, 0]] type='2421 * var * float64'>,
 <Array [[1, -1, 0, 0], ... [-1, 0, 0, 0]] type='2421 * var * int64'>,
 <Array [[4.2, 2.15, 0, 0], ... [0, 0, 0, 0]] type='2421 * var * float64'>)
现在NumPy的
dstack
是合适的。(这使得它们在内存中是连续的,因此如果您愿意,可以使用NumPy的结构化数组。我会发现跟踪哪个索引意味着哪个变量更容易,但这取决于您。实际上,Xarray特别擅长跟踪直线数组的元数据。)


您可能需要将
track_data
dict中的值显式转换为Numpy数组。我从来没有听说过您正在使用的
笨拙数组
根除
工具,所以我不知道它们在这里会做什么。我只是介绍一下关键思想,即:使用Numpy工具来处理Numpy数据。但作为aside,而您自己应该避免显式地迭代Numpy数组(实际上可以保证有一个内置的Numpy东西,它只做您想要的,并且可能比本机Python快得多)np.dstack似乎是这里的tright工具,但我无法理解您的观察结果(我想我缺乏python技能):“对于范围内的I(eventrange):track_array=np.dstack((track_data['track_pt'][I],track_data['track_phi']I],track_data['track_eta']I],轨道数据['track\u dxy'][i],轨道数据['track\u charge'][i])输入轨道阵列[i]=轨道阵列轨道阵列“这就是我现在的立场。这是关于粒子物理学的解释。轨迹是被测量的粒子,我希望它们的变量在一个对象中。但是在一个文件中有几个事件。所以我希望对象/轨迹在单独的数组中。轨迹的数量是可变的。数据将成为神经网络t的输入因此,我希望每个事件的维度是相同的,如果轨迹少于250,它们的值将保持为0。我的代码没有将轨迹放入对象中,但没有按事件排序。我唯一的想法是迭代它们,但这是100%错误的想法。我想你应该问一个新问题。谢谢,这个问题对你很有帮助通过一个与我的问题类似的示例。我想问您如何根据您的选择缩放此脚本:'>>>ak.max(ak.num(μ介子))''4',在接下来的几天中,我必须提取多个根文件。我认为迭代所有文件以获得所有文件的真正“max”是非常不有效的。高猜测是否足够,或者是否足够
>>> ak.num(muons)
<Array [{Muon_Px: 2, ... Muon_Iso: 1}] type='2421 * {"Muon_Px": int64, "Muon_Py"...'>
>>> ak.num(muons)[0].tolist()
{'Muon_Px': 2, 'Muon_Py': 2, 'Muon_Pz': 2, 'Muon_E': 2, 'Muon_Charge': 2, 'Muon_Iso': 2}
>>> ak.max(ak.num(muons))
4
>>> ak.pad_none(muons, ak.max(ak.num(muons)))
<Array [{Muon_Px: [-52.9, 37.7, ... None]}] type='2421 * {"Muon_Px": var * ?floa...'>
{'Muon_Px': [-52.89945602416992, 37.7377815246582, None, None],
 'Muon_Py': [-11.654671669006348, 0.6934735774993896, None, None],
 'Muon_Pz': [-8.16079330444336, -11.307581901550293, None, None],
 'Muon_E': [54.77949905395508, 39.401695251464844, None, None],
 'Muon_Charge': [1, -1, None, None],
 'Muon_Iso': [4.200153350830078, 2.1510612964630127, None, None]}
>>> ak.fill_none(ak.pad_none(muons, ak.max(ak.num(muons))), 0)[0].tolist()
{'Muon_Px': [-52.89945602416992, 37.7377815246582, 0.0, 0.0],
 'Muon_Py': [-11.654671669006348, 0.6934735774993896, 0.0, 0.0],
 'Muon_Pz': [-8.16079330444336, -11.307581901550293, 0.0, 0.0],
 'Muon_E': [54.77949905395508, 39.401695251464844, 0.0, 0.0],
 'Muon_Charge': [1, -1, 0, 0],
 'Muon_Iso': [4.200153350830078, 2.1510612964630127, 0.0, 0.0]}
>>> arrays = ak.unzip(ak.fill_none(ak.pad_none(muons, ak.max(ak.num(muons))), 0))
>>> arrays
(<Array [[-52.9, 37.7, 0, 0, ... 23.9, 0, 0, 0]] type='2421 * var * float64'>,
 <Array [[-11.7, 0.693, 0, 0, ... 0, 0, 0]] type='2421 * var * float64'>,
 <Array [[-8.16, -11.3, 0, 0, ... 0, 0, 0]] type='2421 * var * float64'>,
 <Array [[54.8, 39.4, 0, 0], ... 69.6, 0, 0, 0]] type='2421 * var * float64'>,
 <Array [[1, -1, 0, 0], ... [-1, 0, 0, 0]] type='2421 * var * int64'>,
 <Array [[4.2, 2.15, 0, 0], ... [0, 0, 0, 0]] type='2421 * var * float64'>)
>>> numpy_arrays = [ak.to_numpy(x) for x in arrays]
>>> numpy_arrays
[array([[-52.89945602,  37.73778152,   0.        ,   0.        ],
        [ -0.81645936,   0.        ,   0.        ,   0.        ],
        [ 48.98783112,   0.82756668,   0.        ,   0.        ],
        ...,
        [-29.75678635,   0.        ,   0.        ,   0.        ],
        [  1.14186978,   0.        ,   0.        ,   0.        ],
        [ 23.9132061 ,   0.        ,   0.        ,   0.        ]]),
 array([[-11.65467167,   0.69347358,   0.        ,   0.        ],
        [-24.40425873,   0.        ,   0.        ,   0.        ],
        [-21.72313881,  29.8005085 ,   0.        ,   0.        ],
        ...,
        [-15.30385876,   0.        ,   0.        ,   0.        ],
        [ 63.60956955,   0.        ,   0.        ,   0.        ],
        [-35.66507721,   0.        ,   0.        ,   0.        ]]),
 array([[ -8.1607933 , -11.3075819 ,   0.        ,   0.        ],
        [ 20.19996834,   0.        ,   0.        ,   0.        ],
        [ 11.16828537,  36.96519089,   0.        ,   0.        ],
        ...,
        [-52.66374969,   0.        ,   0.        ,   0.        ],
        [162.17631531,   0.        ,   0.        ,   0.        ],
        [ 54.71943665,   0.        ,   0.        ,   0.        ]]),
 array([[ 54.77949905,  39.40169525,   0.        ,   0.        ],
        [ 31.69044495,   0.        ,   0.        ,   0.        ],
        [ 54.73978806,  47.48885727,   0.        ,   0.        ],
        ...,
        [ 62.39516068,   0.        ,   0.        ,   0.        ],
        [174.20863342,   0.        ,   0.        ,   0.        ],
        [ 69.55621338,   0.        ,   0.        ,   0.        ]]),
 array([[ 1, -1,  0,  0],
        [ 1,  0,  0,  0],
        [ 1, -1,  0,  0],
        ...,
        [-1,  0,  0,  0],
        [-1,  0,  0,  0],
        [-1,  0,  0,  0]]),
 array([[4.20015335, 2.1510613 , 0.        , 0.        ],
        [2.18804741, 0.        , 0.        , 0.        ],
        [1.41282165, 3.38350415, 0.        , 0.        ],
        ...,
        [3.76294518, 0.        , 0.        , 0.        ],
        [0.55081069, 0.        , 0.        , 0.        ],
        [0.        , 0.        , 0.        , 0.        ]])]
>>> import numpy as np
>>> np.dstack(numpy_arrays)
array([[[-52.89945602, -11.65467167,  -8.1607933 ,  54.77949905,
           1.        ,   4.20015335],
        [ 37.73778152,   0.69347358, -11.3075819 ,  39.40169525,
          -1.        ,   2.1510613 ],
        [  0.        ,   0.        ,   0.        ,   0.        ,
           0.        ,   0.        ],
        [  0.        ,   0.        ,   0.        ,   0.        ,
           0.        ,   0.        ]],

       [[ -0.81645936, -24.40425873,  20.19996834,  31.69044495,
           1.        ,   2.18804741],
        [  0.        ,   0.        ,   0.        ,   0.        ,
           0.        ,   0.        ],
        [  0.        ,   0.        ,   0.        ,   0.        ,
           0.        ,   0.        ],
        [  0.        ,   0.        ,   0.        ,   0.        ,
           0.        ,   0.        ]],

       [[ 48.98783112, -21.72313881,  11.16828537,  54.73978806,
           1.        ,   1.41282165],
        [  0.82756668,  29.8005085 ,  36.96519089,  47.48885727,
          -1.        ,   3.38350415],
        [  0.        ,   0.        ,   0.        ,   0.        ,
           0.        ,   0.        ],
        [  0.        ,   0.        ,   0.        ,   0.        ,
           0.        ,   0.        ]],

       ...,

       [[-29.75678635, -15.30385876, -52.66374969,  62.39516068,
          -1.        ,   3.76294518],
        [  0.        ,   0.        ,   0.        ,   0.        ,
           0.        ,   0.        ],
        [  0.        ,   0.        ,   0.        ,   0.        ,
           0.        ,   0.        ],
        [  0.        ,   0.        ,   0.        ,   0.        ,
           0.        ,   0.        ]],

       [[  1.14186978,  63.60956955, 162.17631531, 174.20863342,
          -1.        ,   0.55081069],
        [  0.        ,   0.        ,   0.        ,   0.        ,
           0.        ,   0.        ],
        [  0.        ,   0.        ,   0.        ,   0.        ,
           0.        ,   0.        ],
        [  0.        ,   0.        ,   0.        ,   0.        ,
           0.        ,   0.        ]],

       [[ 23.9132061 , -35.66507721,  54.71943665,  69.55621338,
          -1.        ,   0.        ],
        [  0.        ,   0.        ,   0.        ,   0.        ,
           0.        ,   0.        ],
        [  0.        ,   0.        ,   0.        ,   0.        ,
           0.        ,   0.        ],
        [  0.        ,   0.        ,   0.        ,   0.        ,
           0.        ,   0.        ]]])