1

我们在尴尬的数组中是否已经有了类似于 np.add 的函数?

我处于需要添加它们的情况,并且“+”运算符适用于简单数组但不适用于嵌套数组。

例如 >>> ak.to_list(c1)

[[], [], [], [], [0.944607075944902]]

>>> ak.to_list(c2)

[[0.9800207661211596], [], [], [], []]

>>> c1+c2

回溯(最后一次调用):文件“”,第 1 行,在文件“/afs/cern.ch/work/k/khurana/EXOANALYSIS/CMSSW_11_0_2/src/bbDMNanoAOD/analyzer/dependencies/lib/python3.6/site -packages/numpy/lib/mixins.py”,第 21 行,在 func 返回 ufunc(self, other) 文件“/afs/cern.ch/work/k/khurana/EXOANALYSIS/CMSSW_11_0_2/src/bbDMNanoAOD/analyzer/dependencies /lib/python3.6/site-packages/awkward1/highlevel.py”,第 1380 行,在array_ufunc中 返回尴尬1._connect._numpy.array_ufunc(ufunc,方法,输入,kwargs)文件“/afs/cern.ch/work/k/khurana/EXOANALYSIS/CMSSW_11_0_2/src/bbDMNanoAOD/analyzer/dependencies/lib/python3.6/ site-packages/awkward1/_connect/_numpy.py”,第 107 行,在 array_ufunc 输出 = 尴尬1._util.broadcast_and_apply(输入,getfunction,行为)文件“/afs/cern.ch/work/k/khurana/EXOANALYSIS/CMSSW_11_0_2 /src/bbDMNanoAOD/analyzer/dependencies/lib/python3.6/site-packages/awkward1/_util.py”,第 972 行,在broadcast_and_apply out = apply(broadcast_pack(inputs, isscalar), 0) 文件“/afs/cern .ch/work/k/khurana/EXOANALYSIS/CMSSW_11_0_2/src/bbDMNanoAOD/analyzer/dependencies/lib/python3.6/site-packages/awkward1/_util.py”,第 745 行,应用 outcontent = apply(nextinputs, depth + 1) 文件“/afs/cern.ch/work/k/khurana/EXOANALYSIS/CMSSW_11_0_2/src/bbDMNanoAOD/analyzer/dependencies/lib/python3.6/site-packages/awkward1/_util.py”,第 786 行,在应用 nextinputs.append(x.broadcast_tooffsets64( offsets).content) ValueError:在 ListOffsetArray64 中,无法广播嵌套列表

https://github.com/scikit-hep/awkward-1.0/blob/0.3.1/src/cpu-kernels/operations.cpp#L778

我可以添加它们的唯一方法是使用第一个,然后将 None 替换为 0。

>>> z1=ak.fill_none(ak.firsts(c1),0.)

>>> z2=ak.fill_none(ak.firsts(c2),0.)

>>> z1

<Array [0, 0, 0, 0, 0.945] type='5 * float64'>

>>> z2

<Array [0.98, 0, 0, 0, 0] type='5 * float64'>

>>> z1+z2

<Array [0.98, 0, 0, 0, 0.945] type='5 * float64'>

即使范围/功能有限,也可以为 ak 设计类似于 np.add 的东西。通过有限的范围,我的意思是如果它只能在相同维度的 ak 数组上工作,那么它至少可以满足我目前的目的。

谢谢。

4

1 回答 1

1

你看到的例外

>>> ak.to_list(c1)
[[], [], [], [], [0.944607075944902]]

>>> ak.to_list(c2)
[[0.9800207661211596], [], [], [], []]

>>> c1+c2

是正确的:你不能添加这两个数组。这不是因为 Awkward 缺少ak.add功能。这样的事情将等同于np.add

>>> c1 + c2          # this actually calls np.add
<Array [[], [], [], [], [1.89]] type='5 * var * float64'>
>>> np.add(c1, c1)
<Array [[], [], [], [], [1.89]] type='5 * var * float64'>

它不起作用,因为数组在每个位置都有不同数量的元素。这就像试图添加两个不同形状的 NumPy 数组。(您可以添加具有某些不同形状的NumPy 数组,就像您可以添加具有某些不同形状的 Awkward 数组一样,如果它们广播的话。这些不会。)

如果您希望空列表的行为类似于其中包含零的列表,那么您做对了:ak.firstsak.singletons在表示缺失数据的两种方式之间进行转换:

  • as Nonevs 另一个值
  • 作为空列表与长度为 1 列表中的值。

在某些语言中,缺失或可能缺失的值被视为长度为 0 或长度为 1 的列表,例如Scala 的 Option 类型。因此,

>>> ak.firsts(c1)
<Array [None, None, None, None, 0.945] type='5 * ?float64'>

假设您从空或单例开始(在您的示例中似乎是正确的)并将其转换为深度少一级的选项类型数组。然后执行ak.fill_none意味着您希望这些缺失值(来自空列表)充当加法的零,并且您得到了您想要的。

>>> ak.fill_none(ak.firsts(c1), 0) + ak.fill_none(ak.firsts(c2), 0)
<Array [0.98, 0, 0, 0, 0.945] type='5 * float64'>

从您的数据中不清楚的一件事是您是否总是希望列表最多包含一个项目-<a href="https://awkward-array.readthedocs.io/en/latest/_auto/ak.firsts.html " rel="nofollow noreferrer">ak.firsts 只会从每个列表中拉出第一项。如果你有

>>> c1 = ak.Array([[], [], [], [], [0.999, 0.123]])
>>> c2 = ak.Array([[0.98], [], [], [], []])

然后

>>> ak.fill_none(ak.firsts(c1), 0) + ak.fill_none(ak.firsts(c2), 0)
<Array [0.98, 0, 0, 0, 0.999] type='5 * float64'>

可能不是您想要的,因为它会丢弃0.123. 您实际上可能希望ak.pad_none每个列表至少包含一个元素,如下所示:

>>> ak.pad_none(c1, 1)
<Array [[None], [None], ... [0.999, 0.123]] type='5 * var * ?float64'>
>>> ak.fill_none(ak.pad_none(c1, 1), 0)
<Array [[0], [0], [0], [0], [0.999, 0.123]] type='5 * var * float64'>

这维护了结构,区分除了 0 和 1 之外的所有长度的列表长度,因为空列表已转换为[0]. 除非这些较长的列表匹配长度(回到你原来的问题),否则你不能使用它来添加,但你也可以安排它。

>>> ak.fill_none(ak.pad_none(c1, 2), 0) + ak.fill_none(ak.pad_none(c2, 2), 0)
<Array [[0.98, 0], [0, ... 0], [0.999, 0.123]] type='5 * var * float64'>

这一切都取决于您拥有什么结构以及您想要什么结构。创建一个执行上述两件事之一的新函数并不是一个好主意,特别是如果它的名称与 NumPy 函数的名称非常接近,例如np.add,因为它以不同的方式工作,必须是解释给任何人安全使用它。如果你想做一个专门的事情,让你用更简单的原语构建它会更安全(即使你在自己的工作中把它包装成一个方便的函数),因为这样你就知道它遵循什么规则。

于 2020-10-20T00:17:42.250 回答