【发布时间】:2014-06-26 22:37:08
【问题描述】:
我在使用 NumPy 时遇到的一个反复出现的错误是尝试索引数组失败,因为数组的一个维度是单例,因此该维度被清除并且无法索引。这在设计用于对任意大小的数组进行操作的函数中尤其成问题。我正在寻找最便宜、最通用的方法来避免这个错误。
这是一个例子:
import numpy as np
f = (lambda t, u, i=0: t[:,i]*u[::-1])
a = np.eye(3)
b = np.array([1,2,3])
f(a,b)
f(a[:,0],b[1])
第一次调用按预期工作。第二次调用以两种方式失败:1)t 不能被[:,0] 索引,因为它的形状为(3,),2)u 根本不能被索引,因为它是一个标量。
以下是我遇到的修复:
1) 在f 中使用np.atleast_1d 和np.atleast_2d 等(可能带有条件以确保尺寸顺序正确)以确保所有参数都具有所需的尺寸。这排除了 lambdas 的使用,并且可能需要几行我宁愿不需要的行。
2) 不要在上面写f(a[:,0],b[1]),而是使用f(a[:,[0]],b[[1]])。这很好,但我总是要记住放入额外的括号,如果索引存储在变量中,您可能不知道是否应该放入额外的括号。例如:
idx = 1
f(a[:,[0]],b[[idx]])
idx = [2,0,1]
f(a[:,[0]],b[idx])
在这种情况下,您似乎必须先在idx 上调用np.atleast_1d,这可能比将np.atleast_1d 放入函数中更麻烦。
3) 在某些情况下,我可以侥幸不放入索引。例如:
f = lambda t, u: t[0]*u
f(a,b)
f(a[:,0],b[0])
这很有效,并且在应用时显然是最巧妙的解决方案。但这并不适用于所有情况(特别是,您的尺寸必须以正确的顺序开始)。
那么,还有比上述更好的方法吗?
【问题讨论】:
-
许多 numpy 函数都有很多行 Python 代码,这些代码在执行中心操作之前对输入进行整形和处理。例如,看看
atleast_1d做了什么(它有 10 行长)。 -
我感受到你的痛苦。以下是我通常处理这个问题的方式:首先我存储输入形状并检查输入是否为标量,然后应用
np.atleast_1d之类的东西并进行计算,最后我重塑结果以匹配输入形状(例如变换回到标量)。缺点:这是很多样板。好处:更灵活的界面,对调用者的惊喜更少。我认为作为您的特定领域库的一部分的相当通用的功能是值得的。
标签: python arrays numpy dimensions