【问题标题】:Will results of numpy.as_strided depend on input dtype?numpy.as_strided 的结果是否取决于输入 dtype?
【发布时间】:2018-01-22 22:57:25
【问题描述】:

numpy.lib.stride_tricks.as_strided 的结果会依赖于 NumPy 数组的 dtype 吗?

这个问题源于.strides的定义,即

遍历数组时要在每个维度中步进的字节元组。

使用我在其他问题中使用的以下函数。它采用一维或二维数组并创建长度为window 的重叠窗口。结果将比输入大一维。

def rwindows(a, window):
    if a.ndim == 1:
        a = a.reshape(-1, 1)
    shape = a.shape[0] - window + 1, window, a.shape[-1]
    strides = (a.strides[0],) + a.strides
    windows = np.lib.stride_tricks.as_strided(a, shape=shape, strides=strides)
    return np.squeeze(windows)

# examples
# rwindows(np.arange(5), window=2)
# rwindows(np.arange(20).reshape((5,4)), window=2)

由于步幅的定义,并且例如,否则 dtype float32float64 的等效数组将具有不同的步幅,这是否会炸毁我上面的 rwindows 函数?

我尝试过测试,但它的方式并不详尽,我正在寻找一个答案,即 (1) 解释函数文档中的免责声明/警告是否与我在这里的问题有关,并且(2) 解释了为什么或为什么不具有不同 dtypes & strides 的等价数组会在上面产生不同的结果。

【问题讨论】:

  • 我发现了两个问题。如果形状不正确,您最终可能会“跨过”缓冲区的末端。没有任何保障措施可以确保所有索引值都有效。其次,跨步数组上的许多操作都会进行复制。该副本可能比原始数组或跨步视图大得多;对于多维跨步(2 或 3d 窗口)尤其如此。
  • 嗯。看起来该功能已经足够流行,以至于他们现在正在记录它。

标签: python arrays python-3.x numpy


【解决方案1】:

不,as_strided 的警告是针对两个与数据大小无关的问题,以及更多来自写入结果视图的问题。

  1. 首先,没有任何保护措施可以确保view = as_strided(a . . . ) 指向a 中的内存。这就是为什么在致电as_strided 之前要做这么多深思熟虑的准备工作。如果您的算法关闭,您可以轻松地让您的view 指向不在a 中的内存,并且它可能确实被寻址到垃圾、其他变量或您的操作系统。如果您随后写入该视图,您的数据可能会丢失、放错位置、损坏。 . .或使您的计算机崩溃。

对于您的具体示例,它的安全性在很大程度上取决于您使用的输入。您已将strides 设置为a.strides,因此它是动态的。您可能想assert 认为adtype 并不像object 那样奇怪。

如果你确定你将总是有一个大于window 的二维a,你的算法可能没问题,但你也可以@987654336 @那以确保。如果没有,您可能需要确保 as_strided 输出适用于 n-d a 数组。例如:

shape = a.shape[0] - window + 1, window, a.shape[-1]

应该是

shape = (a.shape[0] - window + 1, window) + a.shape[1:]

为了接受 n-d 输入。 可能就引用坏内存而言永远不会成为问题,但如果您有更多维度,当前的 shape 将引用 a 中的错误数据。

  1. 其次,创建的视图多次引用相同的数据块。如果您随后对该视图进行并行写入(通过view = foobar( . . ., out = view)),结果可能是unpredictable,可能不是您所期望的。

也就是说,如果您害怕出现问题并且不需要写信到as_strided 视图(因为您不需要大多数常用的卷积应用程序),您始终可以将其设置为@987654346 @,即使您的strides 和/或shape 不正确,这也会避免这两个问题。

编辑: 正如@hpaulj 指出的那样,除了这两个问题之外,如果您对制作副本的view 执行某些操作(例如.flatten() 或花式索引大块其中),它可能会导致MemoryError

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2011-06-24
    • 2021-10-06
    • 2012-09-01
    • 2022-01-12
    • 2012-05-29
    • 1970-01-01
    相关资源
    最近更新 更多