根据你的问题,你可能已经意识到所有这些。然而,我发布这个“答案”作为更多的讨论是什么问题,因为很多人可能不知道他们......
如果你不是,但你可以做一个96x96x96x5x5x5
数组,来自100x100x100
图像,充当5x5x5
移动窗口而不分配任何额外的内存。
但是,因为每个维度只能有一个步幅,所以无法在不复制副本的情况下将其重构为96x96x96x125
阵列。
无论如何,这里有一个例子(基本上采取straight from one of my previous answers):
import numpy as np
def rolling_window_lastaxis(a, window):
"""Directly taken from Erik Rigtorp's post to numpy-discussion.
<http://www.mail-archive.com/[email protected]/msg29450.html>"""
if window < 1:
raise ValueError, "`window` must be at least 1."
if window > a.shape[-1]:
raise ValueError, "`window` is too long."
shape = a.shape[:-1] + (a.shape[-1] - window + 1, window)
strides = a.strides + (a.strides[-1],)
return np.lib.stride_tricks.as_strided(a, shape=shape, strides=strides)
def rolling_window(a, window):
"""Takes a numpy array *a* and a sequence of (or single) *window* lengths
and returns a view of *a* that represents a moving window."""
if not hasattr(window, '__iter__'):
return rolling_window_lastaxis(a, window)
for i, win in enumerate(window):
if win > 1:
a = a.swapaxes(i, -1)
a = rolling_window_lastaxis(a, win)
a = a.swapaxes(-2, i)
return a
x = np.zeros((100,100,100), dtype=np.uint8)
y = rolling_window(x, (5,5,5))
print 'Now *y* will be a 96x96x96x5x5x5 array...'
print y.shape
print 'Representing a "rolling window" into *x*...'
y[0,0,0,...] = 1
y[1,1,0,...] = 2
print x[:10,:10,0] # Note that *x* and *y* share the same memory!
这产生了:
Now *y* will be a 96x96x96x5x5x5 array...
(96, 96, 96, 5, 5, 5)
Representing a "rolling window" into *x*...
[[1 1 1 1 1 0 0 0 0 0]
[1 2 2 2 2 2 0 0 0 0]
[1 2 2 2 2 2 0 0 0 0]
[1 2 2 2 2 2 0 0 0 0]
[1 2 2 2 2 2 0 0 0 0]
[0 2 2 2 2 2 0 0 0 0]
[0 0 0 0 0 0 0 0 0 0]
[0 0 0 0 0 0 0 0 0 0]
[0 0 0 0 0 0 0 0 0 0]
[0 0 0 0 0 0 0 0 0 0]]
然而,正如你已经注意到,我们不能这样来重塑96x96x96x125
而不创建副本。 y.shape = (96,96,96,-1)
将引发错误,并且z = y.reshape((96,96,96,-1))
将起作用,但会返回副本。
(相关文件是在numpy.reshape
,如果这样还是很迷惑,基本上reshape
将避免可能的复制时,如果它不是返回副本,而设置shape
属性时,复制是不可能会引发错误。)
但是,即使您构建更高效的阵列容器,sklearn.neighbors.BallTree
几乎肯定会制作临时中间副本。
你提到你正在做图像分割。为什么不研究一个更有效的算法,而不是你似乎正在尝试的相当“蛮力”? (或者如果这不可行,请给我们更多的细节,为什么......也许有人会有更好的主意?)
也需要矢量化图像数据才能在scipy中使用kdtree – Zehan 2012-03-01 14:46:28