首页 > 解决方案 > 笛卡尔(交叉)产品和 np.unique()

问题描述

根据您对我的方法的了解,这要么是关于np.unique()awkward1数组上使用的问题,要么是对更好方法的呼吁:

ab是两个awkward1具有相同外部长度(事件数)但内部长度不同的数组。例如:

a = [[1, 2], [3] , [] , [4, 5, 6]]

b = [[7] , [3, 5], [6], [8, 9]]

f: (x, y) -> z是一个作用于两个数字xy产生数字的函数z。例如:

f(x, y):= y - x

这个想法是将每个事件a的每个元素与bvia中的每个元素进行比较,并f过滤掉在应用于. 例如:abf

f(x, y) < 4

我的方法是:

a = ak.from_iter(a)
b = ak.from_iter(b)

c = ak.cartesian({'x':a, 'y':b})
#c= [[{'x': 1, 'y': 7}, {'x': 2, 'y': 7}], [{'x': 3, 'y': 3}, {'x': 3, 'y': 5}], [], [{'x': 4, 'y': 8}, {'x': 4, 'y': 9}, {'x': 5, 'y': 8}, {'x': 5, 'y': 9}, {'x': 6, 'y': 8}, {'x': 6, 'y': 9}]]

i = ak.argcartesian({'x':a, 'y':b})
#i= [[{'x': 0, 'y': 0}, {'x': 1, 'y': 0}], [{'x': 0, 'y': 0}, {'x': 0, 'y': 1}], [], [{'x': 0, 'y': 0}, {'x': 0, 'y': 1}, {'x': 1, 'y': 0}, {'x': 1, 'y': 1}, {'x': 2, 'y': 0}, {'x': 2, 'y': 1}]]

diff = c['y'] - c['x']
#diff= [[6, 5], [0, 2], [], [4, 5, 3, 4, 2, 3]]

cut = diff < 4
#cut= [[False, False], [True, True], [], [False, False, True, False, True, True]]

new = c[cut]
#new= [[], [{'x': 3, 'y': 3}, {'x': 3, 'y': 5}], [], [{'x': 5, 'y': 8}, {'x': 6, 'y': 8}, {'x': 6, 'y': 9}]]

new_i = i[cut]
#new_i= [[], [{'x': 0, 'y': 0}, {'x': 0, 'y': 1}], [], [{'x': 1, 'y': 0}, {'x': 2, 'y': 0}, {'x': 2, 'y': 1}]]

a与来自相同元素但来自不同元素的配对可能会b在切割中幸存下来。(例如{'x': 3, 'y': 3}{'x': 3, 'y': 5}

我的目标是将具有相同元素的这些对a组合在一起,从而将new数组重塑为:

new = [[], [{'x': 3, 'y': [3, 5]}], [], [{'x': 5, 'y': 8}, {'x': 6, 'y': [8, 9]}]]

我唯一的想法如何实现这一点是创建一个索引列表,a使用以下命令在剪切后仍然存在new_i

i = new_i['x']
#i= [[], [0, 0], [], [1, 2, 2]]

但是,我需要此列表的唯一版本以使每个索引仅出现一次。这可以np.unique()在 NumPy 中实现。但不适用于awkward1

np.unique(i)

<__array_function__ internals> in unique(*args, **kwargs)

TypeError: no implementation found for 'numpy.unique' on types that implement __array_function__: [<class 'awkward1.highlevel.Array'>]

我的问题:

他们是np.unique()等价的awkward1和/或你会推荐一种不同的方法来解决我的问题吗?

标签: pythonawkward-array

解决方案


好的,我仍然不知道如何np.unique()在我的阵列上使用,但我找到了解决我自己问题的方法:

在我之前的方法中,我使用以下代码来配对展位阵列。

c = ak.cartesian({'x':a, 'y':b})
#c= [[{'x': 1, 'y': 7}, {'x': 2, 'y': 7}], [{'x': 3, 'y': 3}, {'x': 3, 'y': 5}], [], [{'x': 4, 'y': 8}, {'x': 4, 'y': 9}, {'x': 5, 'y': 8}, {'x': 5, 'y': 9}, {'x': 6, 'y': 8}, {'x': 6, 'y': 9}]]

但是,使用来自的nested = True参数,ak.cartesian()我得到一个按以下元素分组的列表a

c = ak.cartesian({'x':a, 'y':b}, axis = 1, nested = True)
#c= [[[{'x': 1, 'y': 7}], [{'x': 2, 'y': 7}]], [[{'x': 3, 'y': 3}, {'x': 3, 'y': 5}]], [], [[{'x': 4, 'y': 8}, {'x': 4, 'y': 9}], [{'x': 5, 'y': 8}, {'x': 5, 'y': 9}], [{'x': 6, 'y': 8}, {'x': 6, 'y': 9}]]]

切割后,我最终得到:

new = c[cut]
#new= [[[], []], [[{'x': 3, 'y': 3}, {'x': 3, 'y': 5}]], [], [[], [{'x': 5, 'y': 8}], [{'x': 6, 'y': 8}, {'x': 6, 'y': 9}]]]

我提取y值并将嵌套列表的最内层减少new到只有一个元素:

y = new['y']
#y= [[[], []], [[3, 5]], [], [[], [8], [8, 9]]]

new = ak.firsts(new, axis = 2)
#new= [[None, None], [{'x': 3, 'y': 3}], [], [None, {'x': 5, 'y': 8}, {'x': 6, 'y': 8}]]

(我尝试使用ak.firsts()withaxis = -1但似乎还没有实现。)


现在, in 中的每个最内部条目都new恰好属于 中的一个元素a。通过用之前提取的替换当前y的,我最终得到了我想要的结果:newy

new['y'] = y
#new= [[None, None], [{'x': 3, 'y': [3, 5]}], [], [None, {'x': 5, 'y': [8]}, {'x': 6, 'y': [8, 9]}]]

无论如何,如果您知道更好的解决方案,我会很高兴听到它。


推荐阅读