awkward-array - 为笨拙的数组实现 numpy.linalg.norm
问题描述
目前,不存在 numpy.linalg.norm 与 akward-arrays 的实现。在笨拙的 1 中,我可以behavior
用来覆盖(或添加?)实现,如教程中所示。在我的用例中,我已经成功地实现了和使用np.absolute
教程示例的版本。然而,失败。np.subtract
TVector2
TVector3
numpy.linalg.norm
如何定义笨拙数组的行为?例如,在下面的示例中,我使用一个简单的 int64 数组进行了尝试:
import awkward1 as ak
import numpy as np
def norm(data, *args, **kwargs):
return np.absolute(data)
ak.behavior[np.linalg.norm, "int64"] = norm
sample = ak.Array(np.arange(10))
print(ak.type(sample)) # 10 * int64
print(np.absolute(sample)) # [0, 1, 2, 3, 4, 5, 6, 7, 8, 9]
print(np.linalg.norm(np.arange(10))) # 16.881943016134134
print(np.linalg.norm(sample)) # raises TypeError
解决方案
如果您还没有看到https://awkward-array.readthedocs.io/en/latest/ak.behavior.html,那就从这里开始吧。
如果np.linalg.norm
是一个ufunc,以下应该工作:
ak.behavior[np.linalg.norm, "vector2"] = lambda a: np.sqrt(a.x**2 +a.y**2)
其中数据位于具有字段x
且y
名为 的记录中"vector2"
。你可以用
ak.zip({"x": x_array, "y": y_array}, with_name="vector2")
(警告:我还没有测试过——我是在手机上写的。我稍后会测试并编辑这个答案,或者你可以编辑它。)
如果它不是 ufunc,那么就没有可公开访问(即没有下划线)的方式来定义它,也许应该有。
另外,请注意https://github.com/scikit-hep/vector项目,它定义了这样的操作。
编辑:查看np.linalg.norm文档,你是对的,它不是 ufunc。(isinstance(np.linalg.norm, np.ufunc)
是False
。)
此外,此函数对其输入做出了一些强有力的假设。二维数组被解释为矩阵,而不是向量列表。在 Awkward Array 中,此类区别将由元数据标记。我不认为我们想要实现这样的函数,因为它可能会对本来应该是不同长度向量列表的锯齿状数组造成严重破坏。
我认为您想要的是添加矢量行为,如下所示:
>>> class Vector2(ak.Record):
... @property
... def norm(self):
... return np.sqrt(self.x**2 + self.y**2)
...
>>> class ArrayOfVector2(ak.Array):
... @property
... def norm(self):
... return np.sqrt(self.x**2 + self.y**2)
...
>>> ak.behavior["vector2"] = Vector2
>>> ak.behavior["*", "vector2"] = ArrayOfVector2
这只是说如果你有一个名为 "vector2"
的记录,那么它应该被呈现为 Python 类Vector2
,如果你有一个"vector2"
记录数组(任何深度),它们应该集体呈现为一个ArrayOfVector2
类。
>>> x_array = ak.Array([[1.1, 2.2, 3.3], [], [4.4, 5.5]])
>>> y_array = ak.Array([[1.0, 2.0, 3.0], [], [4.0, 5.0]])
>>> vectors = ak.zip({"x": x_array, "y": y_array}, with_name="vector2")
>>> vectors[0, 0]
<Vector2 {x: 1.1, y: 1} type='vector2["x": float64, "y": float64]'>
>>> vectors
<ArrayOfVector2 [[{x: 1.1, y: 1}, ... y: 5}]] type='3 * var * vector2["x...'>
这使您可以使用已定义的方法和属性:
>>> vectors[0, 0].norm
1.4866068747318506
>>> vectors.norm
<Array [[1.49, 2.97, 4.46], ... [5.95, 7.43]] type='3 * var * float64'>
而且,这正是https://github.com/scikit-hep/vector项目正在做的事情。密切关注它!
推荐阅读
- c - 重定向标准输入和标准输出?
- c - 使用 netbeans 运行 isPrime 程序时出现截断问题
- android - 具有多个活动的问题 Google 同意 sdk (admob)
- sp - Ripleys K 绘图不正确?
- javascript - 需要在 C# 类库中包装 JavaScript API(不是 asp.net 应用程序)
- javascript - 对象集合的 React JS 状态更新
- boolean-logic - 布尔逻辑和真值表
- apache - 网页未加载 CSS。HTTP 有效,HTTPS 无效
- hash - Hash Merge Macro - 使用文件记录指示器“HASH + point = Key”
- selenium-ide - Selenium IDE 3.4.4 for Chrome,找不到运行 Javascript 脚本的语法