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

发布于 2021-01-29 14:58:34

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

这个问题来自的定义.strides,即

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

采取以下我在其他问题中使用过的功能。它需要一个1d或2d数组并创建length的重叠窗口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的等效数组,float32并且float64具有不同的步幅,这是否会炸毁我rwindows上面的函数?

我已经尝试进行测试,但是它只是一种非详尽的方式,正在寻找一个答案,即(1)解释功能doc的免责声明/警告是否与我在此处的要求有关,以及(2)解释了为什么或为什么不同的dtype和stride等价的数组会在上面产生不同的结果。

关注者
0
被浏览
70
1 个回答
  • 面试哥
    面试哥 2021-01-29
    为面试而生,有面试问题,就找面试哥。

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

    1. 首先,没有任何保护措施,以确保view = as_strided(a . . . ) 只有 点记忆a。这就是为什么在致电之前要进行大量的准备工作的原因as_strided。如果您的算法已关闭,则可以轻松地将指针view指向不位于中的内存a,并且确实可以将其指向垃圾,其他变量或您的操作系统。如果随后写入该视图,则数据可能会丢失,放错位置或损坏。。。或使您的计算机崩溃。

    对于您的特定示例,它的安全性在很大程度上取决于您所使用的输入。你已经设置stridesa.strides使是动态的。您可能需要assertdtypea是不奇怪的事情一样object

    如果确定 始终 具有a大于的2-d
    ,则window可能对算法没问题,但也可以assert这样做。如果不是,您可能要确保as_strided输出适用于nda数组。例如:

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

    应该是

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

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

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

    就是说,如果您担心问题并且不需要写入as_strided视图(因为对于大多数常用的卷积应用程序而言,您不需要这样做),则可以始终将其设置为writable = False,即使出现这种情况也可以避免这两个问题您strides和/或shape不正确。

    编辑:
    正如@hpaulj所指出的那样,除了这两个问题外,如果您对view进行复制的操作(像是.flatten()花哨的索引很大一部分),则可能导致MemoryError



知识点
面圈网VIP题库

面圈网VIP题库全新上线,海量真题题库资源。 90大类考试,超10万份考试真题开放下载啦

去下载看看