1

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

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'>]

还有另一种方法可以做到这一点,还是这样?恐怕这对我的申请来说太慢了。

谢谢!

4

1 回答 1

1

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

>>> 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'>

注意类型:valueshas type100 * float64arrhas type 2 * var * int64。没有规则values[arr]

由于看起来您想valuesarr[0]and then切片arr[1](从您的列表理解中),因此可以通过复制values的每个元素arr,然后切片来以矢量化方式完成。

>>> # 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 可以很好地扩展到数千,但不是数十亿(当然,取决于被扩展的事物的大小!)。

于 2021-01-07T18:06:28.340 回答