请问numpy.lib.stride_tricks.as_strided
的结果取决于 NumPy 数组的数据类型?
这个问题源于.strides
的定义,也就是
Tuple of bytes to step in each dimension when traversing an array.
采用我在此处其他问题中使用的以下功能。它采用一维或二维数组并创建长度为 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)解释函数文档中的免责声明/警告是否与我在这里询问的内容有任何关系,以及(2) 解释为什么或为什么不具有不同数据类型和跨度的等价数组会在上面产生不同的结果。
最佳答案
不,as_strided
的警告针对的是两个与数据大小无关的问题,以及写入结果 View 的更多结果。
- 首先,没有确保
view = as_strided(a . . )
仅指向a
中的内存的保护措施。这就是为什么在调用as_strided
之前要进行如此多的准备工作。如果您的算法关闭,您可以很容易地让您的view
指向不在a
中的内存,并且它可能确实被寻址到垃圾、其他变量或您的操作系统。如果您随后写入该 View ,您的数据可能会丢失、错放、损坏。 . .或使您的计算机崩溃。
对于您的具体示例,它的安全性在很大程度上取决于您使用的输入。您已将 strides
设置为 a.strides
,因此这是动态的。您可能想要断言
a
的dtype
不是像object
那样奇怪的东西。
如果您确定您总是有一个大于window
的二维a
,您可能没问题与你的算法,但你也可以 assert
来确保。如果不是,您可能需要确保 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
中的错误数据维度。
- 其次,创建的 View 多次引用相同的数据 block 。如果您随后对该 View 执行并行写入(通过
view = foo
或bar( . . ., out = view)
),结果可能是 unpredictable并且可能不是您所期望的。
就是说,如果您害怕出现问题并且不需要写入 as_strided
View (因为对于大多数常用的卷积应用程序您不需要),您可以随时将其设置为 writable = False
,即使您的 strides
和/或 shape
不正确,这也可以防止这两个问题。
编辑:正如@hpaulj 所指出的,除了这两个问题之外,如果您对生成副本的view
执行某些操作(如. flatten()
或花式索引一大块),它会导致 MemoryError
。
关于python - numpy.as_strided 的结果是否取决于输入数据类型?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/45685772/