And*_*eak 20
笛卡尔空间中单个点的表示有些琐碎。您甚至可以使用平面元组或列表来表示它们,并且矩阵运算仍将起作用,但是如果要添加或缩放它们(从根本上讲,这是线性空间的意思),则必须使用数组。我不明白了一个道理,为什么不使用一维数组与形状(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
Run Code Online (Sandbox Code Playgroud)
更好的问题是如何表示笛卡尔空间中的点集合。如果您有N积分,则可能要使用2d数组。但它应该是其形状,(N, d)或(d, N)?答案取决于您的用例,但您无需选择其他输入即可(N, d)。
默认情况下,numpy中的数组是“ C连续的”,这也称为行主内存布局。这意味着在创建时,数组默认情况下会占用一个连续的内存块,并且项逐行地排列在内存中,以这些索引为例:
>>> np.arange(2*3).reshape(2, 3)
array([[0, 1, 2],
[3, 4, 5]])
Run Code Online (Sandbox Code Playgroud)
我们使用numpy的原因之一是,给定类型的连续内存块比相同大小的本机python容器占用的空间要少得多,至少对于大型数据集而言更是如此。另一个原因是我们可以使用向量化操作,这些向量化操作“同时”对输入的切片进行操作。引号之所以存在是因为从根本上说CPU的双手是束缚在一起的,但是事实证明,通过充分利用CPU高速缓存,可以大大提高速度。这就是内存布局发挥作用的地方:通过对访问内存中关闭元素的数组进行操作,您更有可能利用缓存,而RAM和CPU之间的通信减少将导致运行时间缩短。
这个问题并不简单,因为沿着较大的非连续维度进行矢量化可能比沿着较小的连续维度进行矢量化更快。但是,如果没有任何其他信息,将这些尺寸放在可能要执行矢量化运算和归约的最后一个很好的经验法则上,例如.mean()或.sum()。对于维空间中的N点,d很有可能您希望分别处理每个点。矩阵乘法中的循环以及标量积和向量范数之类的东西都希望您在给定点上使用一个组件,然后处理另一个组件。
这就是为什么您会看到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
[...]
Run Code Online (Sandbox Code Playgroud)
它将多维数组视为矩阵的批次,其中最后两个索引对应于笛卡尔索引。同样,返回的特征值和特征向量首先具有批处理索引,最后具有向量空间索引。
一个更直接的示例是scipy.spatial.distance.pdist计算集合中点对之间的距离:
Parameters
X : ndarray
An m by n array of m original observations in an n-dimensional space.
[...]
Run Code Online (Sandbox Code Playgroud)
同样,您可以看到笛卡尔索引为最后的约定。这同样适用scipy.interpolate.griddata,可能一堆其他的功能。
因此,如果您有充分的理由使用任何一种表示形式,请执行此操作。但是,如果您没有良好的指标(例如,对两个表示进行概要分析的结果),则应坚持使用numpy和scipy(形状(N, d))通常采用的“向量/矩阵批处理”方法,因为您甚至可能最终使用其中一些功能,您的表示将是本机的。
| 归档时间: |
|
| 查看次数: |
383 次 |
| 最近记录: |