numpy中一个点的规范表示是啥?

Posted

技术标签:

【中文标题】numpy中一个点的规范表示是啥?【英文标题】:What is the canonical representation of a point in numpy?numpy中一个点的规范表示是什么? 【发布时间】:2019-12-20 14:06:05 【问题描述】:

我将使用 numpy 进行一些涉及 2-D 和 3D 点的几何计算。

什么是 2-D 或 3-D 点的规范表示?请假设您对 numpy、数据形状等的熟悉程度最低。

【问题讨论】:

这是您的问题,还是提出新规范的设置?很难用标题中的“规范”和高代表用户来判断。 scipy.spatialscipy.interpolate 函数采用“点”数组,但numpy 本身并没有正式使用“点”的概念。像 meshgrid 这样的函数可以从一维数组中创建一个 n-d 坐标网格。 这是我的一个问题,我对numpy等不太了解 【参考方案1】:

笛卡尔空间中单个点的表示有些微不足道。你甚至可以使用平面元组或列表来表示它们,矩阵运算仍然可以工作,但如果你想添加或缩放它们(这基本上是 linear spaces 的用途),你必须使用数组。我看不出为什么不在d 维度中使用形状为(d,) 的一维数组的原因:您可以使用@ matmul 运算符将它们用作矩阵两侧的列向量和行向量:

import numpy as np 

rot90 = np.array([[0, -1, 0], [1, 0, 0], [0, 0, 1]])  # rotate 90 degrees around z
inp = np.array([1, 0, 0])  # x 

# rotate: 
inp_rot = rot90 @ inp  # y 
# inverse transform: 
inp_invrot = inp @ rot90  # -y 

一个更好的问题是如何在笛卡尔空间中表示集合。如果您有N 点,您可能想要使用二维数组。但它应该是哪个形状,(N, d)(d, N)?答案取决于您的用例,但如果没有进一步的输入,您需要选择(N, d)

默认情况下,numpy 中的数组是“C 连续”的,也称为行优先内存布局。这意味着在创建时,数组默认占用一个连续的内存块,并且项目在内存中逐行排列,以这些索引为例:

>>> np.arange(2*3).reshape(2, 3)
array([[0, 1, 2],
       [3, 4, 5]])

我们使用 numpy 的原因之一是给定类型的连续内存块占用的空间比相同大小的本机 python 容器要少得多,至少对于大型数据集而言。另一个原因是我们可以使用“同时”处理输入切片的向量化操作。之所以有引号,是因为从根本上说 CPU 的双手是受束缚的,但事实证明,通过充分利用 CPU 缓存,您可以实现相当多的加速。这就是内存布局发挥作用的地方:通过在数组上使用访问靠近内存的元素的操作,您就有更高的机会利用缓存,而 RAM 和 CPU 之间的通信减少将导致运行时间更短。

这个问题并不是微不足道的,因为沿较大的非连续维度进行矢量化最终可能比沿较小的连续维度进行矢量化更快。但是,如果没有任何其他信息,最好将这些维度放在您可能执行矢量化操作和缩减的最后,例如.mean().sum()。对于d 维空间中的N 点,您很可能希望分别处理每个点。矩阵乘法中的循环以及诸如标量积和向量范数之类的东西都希望您在给定点上一个接一个地使用一个组件。

这就是为什么您会看到 numpy 和 scipy 函数通常假定形状为 (N, d) 的数组:内部维度是第二个,“批处理”索引是第一个。例如numpy.linalg.eig:

Parameters: 

a : (…, M, M) array

    Matrices for which the eigenvalues and right eigenvectors will be computed

Returns:    

w : (…, M) array

    The eigenvalues, each repeated according to its multiplicity. The eigenvalues
    are not necessarily ordered. The resulting array will be of complex type,
    unless the imaginary part is zero in which case it will be cast to a real
    type. When a is real the resulting eigenvalues will be real (0 imaginary
    part) or occur in conjugate pairs

[...]

它将多维数组视为矩阵批次,其中最后两个索引对应于笛卡尔索引。类似地,返回的特征值和特征向量首先具有批索引,最后具有向量空间索引。

一个更直接的例子是scipy.spatial.distance.pdist,它计算集合中点对之间的距离:

Parameters

    X : ndarray
        An m by n array of m original observations in an n-dimensional space.

[...]

您可以再次看到笛卡尔索引在最后的约定。 scipy.interpolate.griddata 也是如此,可能还有许多其他功能。

因此,如果您有充分的理由使用任一表示:那就这样做吧。但是,如果您没有一个好的指标(例如分析两种表示的结果),您应该坚持使用 numpy 和 scipy(形状 (N, d))通常使用的“批量向量/矩阵”方法,因为您甚至可能最终使用其中一些函数,然后您的表示将是本机的。

【讨论】:

【参考方案2】:

在源代码中将它们表示为元组或列表,例如(1, 0)[1, 0, 1]

根据scipy的这个例子:

>>> from scipy.spatial import distance
>>> distance.euclidean([1, 0, 0], [0, 1, 0])
1.4142135623730951

【讨论】:

这是个好问题。 [1,0,0] 是线索。作为一个排名初学者,我不知道我是否在寻找 Point() 类,一些神奇的语法等,我正在寻找某种 Point() 类或类似的东西;事实证明,列表或元组是常用的。在这方面,由于您的专业知识,您可能处于劣势,因为点表示已深深嵌入您的大脑中,因此不会像我这样的初学者感到困惑。 @Adriaan,啊,我看到你添加了一个赏金,这可能是你感兴趣的原因。请注意,我最初将我的观察(实际上是我发现让我继续发扬光大的)添加到了 Andras 出色的文章中。但请注意,他的大部分文章实际上都回答了他自己的问题:“一个更好的问题是如何表示笛卡尔空间中的点集合。”。历史显示他删除了我的 tldr,所以我将其添加为单独的答案。我尊重他的意愿;如果答案包括我需要的快速线索,我会重新接受他的回答。 @Adrinn,我应该说,如果你能说服 Andras 恢复顶部的 tldr(它回答了我头脑简单的问题!)我很乐意重新选择他的答案并删除我的。我也应该感谢你足够关心提出这个问题! 这就是“按”的意思,但如果您认为这样更好,我很乐意澄清。对于像我这样的简单头脑,“行明智”往往会通过回答我没有考虑的问题来混淆事物。把我想象成你试图弄清楚如何打印 hello world 而不需要解释设备、驱动程序等的基本傻瓜。

以上是关于numpy中一个点的规范表示是啥?的主要内容,如果未能解决你的问题,请参考以下文章

一个圈里面一个点的数学符号是啥意思

Numpy 规范化代码异常缓慢

C++:“float”的 printf() 格式规范是啥?

在 Python NumPy 中,维度和轴是啥?

在C++种,关于指针的这两种表示有啥区别:double * a和double ** a?两个**是啥意思呢?

python语言常见的三种括号区别是啥?