重复的numpy子阵列

时间:2011-11-19 14:42:08

标签: python numpy

这是我的问题的简化。我有一个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数组子类化为此。

任何提示赞赏。

1 个答案:

答案 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的视图。