将笨拙的数组与索引数组一起使用时出错

Error when using an awkward array with an index array

我目前有一个值列表和一个笨拙的整数值数组。我想要相同维度的笨拙数组,但其中的值是与笨拙数组的整数值对应的“值”数组的索引。例如:

values = ak.Array(np.random.rand(100))
arr = ak.Array((np.random.randint(0, 100, 33), np.random.randint(0, 100, 125)))

我想要类似 values[arr] 的东西,但会出现以下错误:

>>> values[arr]
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
  File "C:\Anaconda3\lib\site-packages\awkward\highlevel.py", line 943, in __getitem__
    return ak._util.wrap(self._layout[where], self._behavior)
ValueError: cannot fit jagged slice with length 2 into RegularArray of size 100

如果我运行它有一个循环,我会得到我想要的:

>>> values = ([values[i] for i in arr])
>>> values
[<Array [0.842, 0.578, 0.159, ... 0.726, 0.702] type='33 * float64'>, <Array [0.509, 0.45, 0.202, ... 0.906, 0.367] type='125 * float64'>]

有没有其他方法可以做到这一点,或者就是这样?恐怕它对我的应用程序来说太慢了。

谢谢!

如果您试图避免 Python for 循环以提高性能,请注意第一行将 NumPy 数组转换为 Awkward with ak.from_numpy(无循环,非常快):

>>> values = ak.Array(np.random.rand(100))

但第二行遍历 Python 中的数据(有一个慢循环):

>>> arr = ak.Array((np.random.randint(0, 100, 33), np.random.randint(0, 100, 125)))

因为两个 NumPy 数组的元组不是 NumPy 数组。它是一个通用的可迭代对象,构造函数回落到 ak.from_iter.

关于你的主要问题,arr 不分割 values 的原因是因为 arr 是锯齿状数组而 values 不是:

>>> values
<Array [0.272, 0.121, 0.167, ... 0.152, 0.514] type='100 * float64'>
>>> arr
<Array [[15, 24, 9, 42, ... 35, 75, 20, 10]] type='2 * var * int64'>

注意类型:values 的类型为 100 * float64arr 的类型为 2 * var * int64values[arr].

没有规则

因为看起来你想用 arr[0] 切片 values 然后 arr[1] (从你的列表理解),它可以通过复制 valuesarr的每个元素进行切片。

>>> # The np.newaxis is to give values a length-1 dimension before concatenating.
>>> duplicated = ak.concatenate([values[np.newaxis]] * 2)
>>> duplicated
<Array [[0.272, 0.121, ... 0.152, 0.514]] type='2 * 100 * float64'>

现在 duplicated 的长度为 2,嵌套一层,就像 arr 一样,所以 arr 可以对其进行切片。结果数组的长度也是2,但是每个子列表的长度是arr中每个子列表的长度,而不是100.

>>> duplicated[arr]
<Array [[0.225, 0.812, ... 0.779, 0.665]] type='2 * var * float64'>
>>> ak.num(duplicated[arr])
<Array [33, 125] type='2 * int64'>

如果您要从 2 个这样的列表扩展到大量列表,那么这会占用大量内存。然后,此操作的输出大小也将缩放为“values 的长度”דarr 的长度”。如果这个“2”不会扩大(如果它最多是数千,而不是数百万或更多),那么我就不会担心 Python for 循环的速度。 Python 可以很好地扩展到数千个,但不能扩展到数十亿个(当然,取决于要扩展的事物的大小!)。