python - 笛卡尔(交叉)产品和 np.unique()
问题描述
根据您对我的方法的了解,这要么是关于np.unique()
在awkward1
数组上使用的问题,要么是对更好方法的呼吁:
设a
和b
是两个awkward1
具有相同外部长度(事件数)但内部长度不同的数组。例如:
a = [[1, 2], [3] , [] , [4, 5, 6]]
b = [[7] , [3, 5], [6], [8, 9]]
让f: (x, y) -> z
是一个作用于两个数字x
并y
产生数字的函数z
。例如:
f(x, y):= y - x
这个想法是将每个事件a
的每个元素与b
via中的每个元素进行比较,并f
过滤掉在应用于. 例如:a
b
f
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
和/或你会推荐一种不同的方法来解决我的问题吗?
解决方案
好的,我仍然不知道如何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
的,我最终得到了我想要的结果:new
y
new['y'] = y
#new= [[None, None], [{'x': 3, 'y': [3, 5]}], [], [None, {'x': 5, 'y': [8]}, {'x': 6, 'y': [8, 9]}]]
无论如何,如果您知道更好的解决方案,我会很高兴听到它。