我的理解是,numpy 中的一维数组可以解释为面向列的向量或面向行的向量。例如,形状为 (8,)
的一维数组可以被视为形状为 (1,8)
或形状为 ( 8,1)
取决于上下文。
我遇到的问题是,我编写的用于操作数组的函数往往在二维情况下可以很好地泛化以处理向量和矩阵,但在一维情况下则不太好。
因此,我的函数最终会执行如下操作:
if arr.ndim == 1:
# Do it this way
else:
# Do it that way
甚至这样:
# Reshape the 1-D array to a 2-D array
if arr.ndim == 1:
arr = arr.reshape((1, arr.shape[0]))
# ... Do it the 2-D way ...
也就是说,我发现我可以概括代码来处理二维情况 (r,1)
, (1,c)
, (r, c)
,但不是没有分支或 reshape 的一维情况。
当函数在多个数组上运行时,它会变得更加丑陋,因为我会检查并转换每个参数。
所以我的问题是:我是否遗漏了一些更好的成语?我上面描述的模式对 numpy 代码是通用的吗?
此外,作为 API 设计原则的相关问题,如果调用者将一个一维数组传递给某个返回新数组的函数,并且返回值也是一个向量,那么 reshape 一个二维数组是否是常见的做法? D 向量 (r,1)
或 (1,c)
返回一维数组,还是简单地记录函数返回二维数组?
谢谢
最佳答案
我认为一般来说,需要形状为 (r,c)
的数组的 NumPy 函数不会特别考虑一维数组。相反,他们希望用户传递一个形状为 (r,c)
的数组,或者让用户传递一个一维数组 broadcasts直到形状 (r,c)
。
如果您将形状为 (c,)
的一维数组传递给这样的函数,它将广播到形状 (1,c)
,因为广播添加了新轴在左边。它还可以为任意 r
广播形状 (r,c)
(取决于与它组合的其他数组)。
另一方面,如果您有一个形状为 (r,)
的一维数组 x
并且您需要它广播形状为 (r,c)
,那么 NumPy 希望用户传递形状为 (r,1)
的数组,因为广播不会为您在右侧添加新轴。
为此,用户必须传递 x[:,np.newaxis]
而不仅仅是 x
。
关于返回值:我认为最好总是返回一个二维数组。如果用户知道输出的形状为 (1,c)
,并且想要一个一维数组,让她切掉一维数组 x[0]
她自己。
通过使返回值始终具有相同的形状,将更容易理解使用此函数的代码,因为输入的形状并不总是很明显。
此外,广播模糊了形状为 (c,)
的一维数组和形状为 (r,c)
的二维数组之间的区别。如果您的函数在提供一维输入时返回一维数组,在提供二维输入时返回二维数组,那么您的函数会严格区分而不是模糊。从风格上讲,这让我想起了检查 if isinstance(obj,type)
,这与 duck-typing 的本质背道而驰。如果没有必要,请不要这样做。
关于python - 编写接受一维和二维 numpy 数组的函数?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/8287047/