numpy.as_strided的结果是否取决于输入dtype?

时间:2017-08-15 02:42:14

标签: python arrays python-3.x numpy

numpy.lib.stride_tricks.as_strided的结果是否取决于NumPy数组的dtype?

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

  

遍历数组时每个维度中的字节元组。

在此处使用我在其他问题中使用的以下功能。它需要1d或2d数组并创建长度为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数组将有不同的步幅,这会不会爆炸我{ {1}}上面的功能?

我已经尝试过测试,但它一直是非详尽无遗的,我正在寻找一个答案,(1)解释功能文档中的免责声明/警告是否与什么有关我在这里问,(2)解释了为什么或为什么没有其他等效的数组具有不同的dtypes&大步会在上面产生不同的结果。

1 个答案:

答案 0 :(得分:4)

不,as_strided的警告是针对两个与数据大小无关的问题,而是写入结果视图的结果。

  1. 首先,没有任何保护可以确保view = as_strided(a . . . ) 指向a中的内存。这就是为什么在致电as_strided之前已经做了如此多的刻意准备工作。如果您的算法已关闭,您可以轻松地将view指向不在a中的内存,并且可能确实将其发送到垃圾,其他变量或操作系统。如果您随后写入该视图,您的数据可能会丢失,放错位置,损坏。 。 。或者崩溃你的电脑。
  2. 对于您的具体示例,它的安全程度取决于您正在使用的输入。您已将strides设置为a.strides,因此这是动态的。您可能希望assert dtype a object不像a那样奇怪。

    如果您确定总是的{2} window大于assert,那么您的算法可能会很好,但是你还可以as_strided来确保。如果没有,您可能需要确保a输出适用于n-d shape = a.shape[0] - window + 1, window, a.shape[-1] 数组。例如:

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

    应该是

    shape

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

    1. 其次,创建的视图多次引用相同的数据块。如果您然后对该视图进行并行写入(通过bar( . . ., out = view)as_strided),则结果可能是unpredictable,可能不是您所期望的。
    2. 也就是说,如果您害怕出现问题并且不需要写入writable = False视图(因为您不常用于大多数常用的卷积应用程序),您可以随时将其设置为strides,即使您的shape和/或view不正确,也会阻止这两个问题。

      编辑:正如@hpaulj指出的那样,除了这两个问题之外,如果你对.flatten()做了一些复制(MemoryError或者幻想索引其中的一大块),它可能会导致public class Box { [InverseProperty("IncomingBox")] public IList<BoxContentItem> IncomingBoxContentItems { get; set; } [InverseProperty("OutgoingBox")] public IList<BoxContentItem> OutgoingBoxContentItems { get; set; } }