我有一些适合JaggedArrays
提取content
,starts
,stops
的代码,但是我想在某些ChunkedArrays
上运行相同的代码,这些lazyarrays
是从uproot
的获取的。
不幸的是,我得到了以下错误:
~/.local/lib/python3.7/site-packages/awkward/array/base.py in __getattr__(self, where)
254 raise AttributeError("while trying to get column {0}, an exception occurred:\n{1}: {2}".format(repr(where), type(err), str(err)))
255 else:
--> 256 raise AttributeError("no column named {0}".format(repr(where)))
257
258 def __dir__(self):
AttributeError: no column named 'starts'
有什么办法可以使它起作用?
最佳答案
逐渐变得清楚的是,诸如starts
,stops
和content
之类的属性不应公开,它们应被视为内部属性。它们是使JaggedArray
工作的一部分,但不是任何锯齿数据的属性(对于某些数组长度type
和内部类型[0, N) -> [0, inf) -> X
,其N
为X
的任何数组)。
您不希望您的锯齿数据是ChunkedArray
,并且对于许多操作(例如flatten()
和counts
),您都不在乎:它们在ChunkedArray
上与JaggedArray
同样有效。但是starts
,stops
和content
永远不会像这样:除了JaggedArray
的特定实现之外,它们没有其他意义。
例如,考虑以下ChunkedArray
:
>>> array = awkward.ChunkedArray([awkward.fromiter([[1, 2, 3], [], [4, 5]]),
... awkward.fromiter([[100], [200, 300]])])
>>> array
<ChunkedArray [[1 2 3] [] [4 5] [100] [200 300]] at 0x796a969db6a0>
我们可以得到每个
starts
的stops
和chunk
,但这可能不是您想要的:>>> [x.starts for x in array.chunks]
[array([0, 3, 3]), array([0, 1])]
>>> [x.stops for x in array.chunks]
[array([3, 3, 5]), array([1, 3])]
(在您的情况下,您有惰性数组,它们是
ChunkedArray
的VirtualArray
,因此您必须执行x.array.starts
而不是x.starts
来解包VirtualArray
。这可能是另一个属性出于相同的原因)。注意第二个
starts
的chunk
从0
重新开始吗?这是因为索引是相对于您当前的chunk
的(因此chunks
可以并行处理)。如果将starts
用作数据分析的一部分,那将是一个重要的更正。 (您可以将前一个stops[-1] if len(stops) > 0 else 0
的chunk
添加到当前的chunk
中,以使数字具有全局性。)也许更好的选择是从
counts
构造有意义的偏移量。 ChunkedArray
具有正常运行的counts
:>>> array.counts
array([3, 0, 2, 1, 2])
counts
是锯齿状数据中每个子数组的长度,是offsets
的派生形式,starts
和stops
重叠:>>> offsets = numpy.empty(len(array) + 1, dtype=int)
>>> offsets[0] = 0
>>> numpy.cumsum(array.counts, out=offsets[1:])
array([3, 3, 5, 6, 8])
>>> offsets
array([0, 3, 3, 5, 6, 8])
>>> starts, stops = offsets[:-1], offsets[1:]
>>> starts
array([0, 3, 3, 5, 6])
>>> stops
array([3, 3, 5, 6, 8])
您可以将它们用作
starts
和stops
,但前提是您有某种且它们与starts
和stops
完全相邻。不能保证JaggedArray
的content
,但是flatten()
会为您做到这一点:>>> content = array.flatten()
>>> content
<ChunkedArray [1 2 3 ... 100 200 300] at 0x796aa12b1940>
现在,例如,索引为
3
的子数组为>>> content[starts[3]:stops[3]]
<ChunkedArray [100] at 0x796a96a3b978>
这就是为什么尴尬的0的
ChunkedArray
,JaggedArray
等将成为内部的“仅面向专家”类的原因。尴尬1中的用户界面将只有一个awkward.Array
类和一个type
来了解其是否呈锯齿状。无论是用块还是其他东西制成,都将是实现细节。