这是我的问题的简化。我有一个numpy数组:
x = np.array([0,1,2,3])
我有一个功能:
def f(y): return y**2
我可以计算f(x)。
现在假设我真的想为重复的x计算f(x):
x = np.array([0,1,2,3,0,1,2,3,0,1,2,3])
有没有办法在不创建x的重复版本且以对f透明的方式执行此操作?
在我的特定情况下,f是一个涉及的函数,其中一个参数是x。我希望能够在重复x时计算f而不重复它,因为它不适合内存。
重写f来处理重复的x将是有效的,我希望有一种聪明的方法可能将numpy数组子类化为此。
任何提示赞赏。
答案 0 :(得分:8)
你可以(几乎)通过大步使用一些技巧来做到这一点。
然而,有一些重要的警告......
import numpy as np
x = np.arange(4)
numrepeats = 3
y = np.lib.stride_tricks.as_strided(x, (numrepeats,)+x.shape, (0,)+x.strides)
print y
x[0] = 9
print y
因此,y
现在是x
的视图,其中每一行都是x
。没有使用新内存,我们可以使y
尽可能大。
例如,我可以这样做:
import numpy as np
x = np.arange(4)
numrepeats = 1e15
y = np.lib.stride_tricks.as_strided(x, (numrepeats,)+x.shape, (0,)+x.strides)
...并且不再使用x
所需的32字节以外的内存。 (y
将使用~8 Petabytes 的ram,否则)
但是,如果我们重塑y
以便它只有一个维度,我们将获得一个使用全部内存的副本。无法使用步幅和形状来描述x
的“水平”平铺视图,因此任何尺寸小于2的形状都将返回副本。
此外,如果我们以y
的方式操作以返回副本(例如示例中的y**2
),我们将获得完整副本。
因此,在现场操作更有意义。 (例如y **= 2
,或等效x **= 2
。两者都会完成同样的事情。)
即使是通用功能,您也可以传递x
并将结果放回x
。
E.g。
def f(x):
return x**3
x[...] = f(x)
print y
y
也会更新,因为它只是x
的视图。