【发布时间】:2023-03-29 18:19:01
【问题描述】:
我有一个大型 2D 数组,我想声明一次,并且偶尔只根据参数更改 一些 值,而不遍历整个数组。
为了构建这个数组,我使用dtype=object 对 numpy ndarray 类进行了子类化,并分配给我想要更改函数的元素,例如:
def f(parameter):
return parameter**2
for i in range(np.shape(A)[0]):
A[i,i]=f
for j in range(np.shape(A)[0]):
A[i,j]=1.
然后我重写了__getitem__ 方法,以便它返回具有给定参数的函数的求值,如果它是可调用的,否则返回值本身。
def __getitem__(self, key):
value = super(numpy.ndarray, self).__getitem__(key)
if callable(value):
return value(*self.args)
else:
return value
self.args 以前被赋予 myclass 的实例。
但是,最后我需要使用浮点数组,而且我不能使用这种技术简单地将这个数组转换为dtype=float 数组。我还尝试使用 numpy 视图,这对于 dtype=object 也不起作用。
你有更好的选择吗?我应该覆盖视图方法而不是 getitem 吗?
编辑我将来可能不得不使用 Cython,所以如果你有一个解决方案涉及例如C指针,我有兴趣。
【问题讨论】:
-
这是一种有趣的方法,但我不确定 numpy 数组是否适合它。通常,当您使用 numpy 时,您将使用使用完整数组或切片的矢量化操作,而不是逐个元素访问。以您的方式对 ndarray 进行子类化,您基本上失去了快速 numpy 操作的所有优势。您最好从零创建自己的类并将所有内容保存为纯 python 结构(列表等)。在性能方面,它将具有可比性。为什么你真的需要惰性评估?您可以使用精美的索引有效地更改某些元素。
-
你只有一个函数
f吗?有常量参数? -
你熟悉
scipy.sparse吗?dok格式是一个字典,(i,j)元组作为键。那和lil(列表列表)是访问/更改所选项目的两种最快方式。 -
@hpaulj : dok 很有趣。但是,我不能将它与 dtype=object 一起使用,就像我上面展示的示例一样:github.com/scipy/scipy/issues/2528
-
@rth:我需要惰性求值而不是使用键(甚至有效)访问数组的原因是,每种影响都可能与不同类型的索引有关。对于上面的示例,我只将对角线设置为可变的。例如,我也可以将一行(或更复杂的)影响到另一个函数 g。
标签: python arrays numpy multidimensional-array lazy-evaluation