重复的numpy子阵列

Pau*_*aul 4 python numpy

这是我的问题的简化.我有一个numpy数组:

x = np.array([0,1,2,3])
Run Code Online (Sandbox Code Playgroud)

我有一个功能:

def f(y): return y**2
Run Code Online (Sandbox Code Playgroud)

我可以计算f(x).

现在假设我真的想为重复的x计算f(x):

x = np.array([0,1,2,3,0,1,2,3,0,1,2,3])
Run Code Online (Sandbox Code Playgroud)

有没有办法在不创建x的重复版本的情况下以一种对f透明的方式执行此操作?

在我的特定情况下,f是一个涉及的函数,其中一个参数是x.我希望能够在重复x时计算f而不实际重复它,因为它不适合内存.

重写f以处理重复的x将是有效的,我希望有一种聪明的方法可能将numpy数组子类化为此.

任何提示赞赏.

Joe*_*ton 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
Run Code Online (Sandbox Code Playgroud)

因此,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)
Run Code Online (Sandbox Code Playgroud)

...而不是使用超过32字节所需的内存x.(y会使用~ 8PB的ram,否则)

但是,如果我们重塑y它只有一个维度,我们将获得一个使用全部内存的副本.无法描述x使用步幅和形状的"水平"平铺视图,因此任何小于2维的形状都将返回副本.

此外,如果我们以y返回副本的方式进行操作(例如,y**2在您的示例中),我们将获得完整副本.

出于这个原因,对现场操作更有意义.(例如y **= 2,或等同x **= 2.两者都将完成同样的事情.)

即使对于通用函数,您也可以传入x并放回结果x.

例如

def f(x):
    return x**3

x[...] = f(x)
print y
Run Code Online (Sandbox Code Playgroud)

y将会更新,因为它只是一个视图x.