将笨拙的数组与索引数组一起使用时出错
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 * float64
,arr
的类型为 2 * var * int64
。 values[arr]
.
没有规则
因为看起来你想用 arr[0]
切片 values
然后 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 可以很好地扩展到数千个,但不能扩展到数十亿个(当然,取决于要扩展的事物的大小!)。
我目前有一个值列表和一个笨拙的整数值数组。我想要相同维度的笨拙数组,但其中的值是与笨拙数组的整数值对应的“值”数组的索引。例如:
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 * float64
,arr
的类型为 2 * var * int64
。 values[arr]
.
因为看起来你想用 arr[0]
切片 values
然后 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 可以很好地扩展到数千个,但不能扩展到数十亿个(当然,取决于要扩展的事物的大小!)。