【问题标题】:repeated numpy subarrays重复的numpy子数组
【发布时间】:2011-11-19 14:42:07
【问题描述】:

这是对我的问题的简化。我有一个 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 数组来做到这一点。

感谢任何提示。

【问题讨论】:

  • 澄清一下,您是否正在寻找一种有效的数据结构来保存块形式的矩阵(A A A) 用于某些矩阵A
  • @katrielex 是的,没错。

标签: python numpy


【解决方案1】:

你可以(几乎)通过使用一些大步的技巧来做到这一点。

但是,有一些主要的警告......

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 PB 内存,否则)

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

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

因此,就地操作更有意义。 (例如y **= 2,或等效的x **= 2。两者都会完成同样的事情。)

即使是泛型函数,您也可以传入x 并将结果放回x

例如

def f(x):
    return x**3

x[...] = f(x)
print y

y 也将更新,因为它只是x 的视图。

【讨论】:

  • 这很聪明。谢谢乔。我将重写我的代码以使用 stride_tricks 并避免您指出的警告。
猜你喜欢
  • 1970-01-01
  • 2020-12-05
  • 1970-01-01
  • 2015-09-14
  • 1970-01-01
  • 2017-02-25
  • 2020-04-03
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多