结果是否numpy.lib.stride_tricks.as_strided取决于 NumPy 数组的 dtype?
numpy.lib.stride_tricks.as_strided
这个问题源于 的定义.strides,即
.strides
遍历数组时在每个维度中要步进的字节元组。
以我在其他问题中使用过的以下函数为例。它接受一维或二维数组并创建长度为 的重叠窗口window。结果将比输入大一维。
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上面的函数吗?
float32``float64
rwindows
我曾尝试进行测试,但测试方式并不详尽,我正在寻找一个答案,该答案可以(1)解释函数文档中的免责声明/警告是否与我在此处询问的内容有关,以及(2)解释为什么或为什么不具有不同 dtypes 和 strides 的等效数组会在上述内容中产生不同的结果。
不,警告针对的as_strided是两个问题,实际上与数据大小无关,更多是因写入结果视图而导致的。
as_strided
view = as_strided(a . . . )
a
view
对于您的具体示例,其安全性在很大程度上取决于您使用的输入。您已设置,strides因此它a.strides是动态的。您可能希望assert不是像这样奇怪的东西。dtype``a``object
strides
a.strides
assert
dtype``a``object
如果您确定总会有a一个大于的二维数组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。
shape
view = foo
bar( . . ., out = view)
也就是说,如果您担心出现问题并且不需要写入视图as_strided(因为在大多数常用的卷积应用程序中您不需要写入视图),您可以随时将其设置为writable = False,即使您的strides和/或shape不正确,这也可以防止出现这两个问题。
writable = False
编辑:正如@hpaulj 指出的那样,除了这两个问题之外,如果你对 a 做了一些view复制(比如.flatten()或想索引它的一大块),它可能会导致MemoryError。
.flatten()
MemoryError