将 Numpy 数组重塑为形状 (n, n, n) 立方体的字典列表 [英] Reshaping a Numpy Array into lexicographical list of cubes of shape (n, n, n)

查看:39
本文介绍了将 Numpy 数组重塑为形状 (n, n, n) 立方体的字典列表的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

为了理解我想要实现的目标,让我们想象一个形状为 (8,8,8) 的 ndarray a,我从中按字典顺序提取了形状块(4,4,4).因此,在遍历这些块时,索引将如下所示:

In order to understand what I'm trying to achieve let's imagine an ndarray a with shape (8,8,8) from which I lexicographically take blocks of shape (4,4,4). So while iterating through such blocks the indexes would look as follows:

0: a[0:4, 0:4, 0:4]  
1: a[0:4, 0:4, 4:8]  
2: a[0:4, 4:8, 0:4]  
3: a[0:4, 4:8, 4:8]  
4: a[4:8, 0:4, 0:4]  
5: a[4:8, 0:4, 4:8]  
6: a[4:8, 4:8, 0:4]  
7: a[4:8, 4:8, 4:8]  

我正试图访问这些数据块.显然,这可以通过使用将当前迭代转换为相应索引的表达式来描述.下面给出了一个例子.

It is these blocks of data which I'm trying to access. Obviously, this can be described by using an expression which converts the current iteration to the corresponding indexes. An example of that is given below.

a = np.ones((8,8,8))
f = 4

length = round(a.shape[0] * a.shape[1] * a.shape[2] / f**3)

x = a.shape[0] / f
y = a.shape[1] / f
z = a.shape[2] / f

for i in range(length):
    print(f"{i}: {round((int(i/(z*y))%x)*f)}:{round(f+(int(i/(z*y))%x)*f)}, {round((int(i/z)%y)*f)}:{round(f+(int(i/z)%y)*f)}, {round((i%z)*f)}:{round(f+(i%z)*f)}")

我很抱歉不得不对您的眼睛这样做,但它会生成以下输出:

My apologies for having to do that to your eyes but it generates the following output:

0: 0:4, 0:4, 0:4
1: 0:4, 0:4, 4:8
2: 0:4, 4:8, 0:4
3: 0:4, 4:8, 4:8
4: 4:8, 0:4, 0:4
5: 4:8, 0:4, 4:8
6: 4:8, 4:8, 0:4
7: 4:8, 4:8, 4:8

所以这实际上生成了正确的索引,但它只允许您一次访问多个块,如果它们在第 0 轴和第 1 轴上具有相同的索引,所以没有回绕.理想情况下,我会将整个 ndarray 重塑为形状为 (4, 4, 32) 的 ndarray b 并以 b[:, 的方式排序:, :4] 将返回 a[0:4, 0:4, 0:4], b[:, :, 4:12] 返回一个形状为 (4, 4, 8) 的 ndarray,其中包含 a[0:4, 0:4, 4:8]a[0:4, 4:8, 0:4] 等等.我希望它尽可能快,所以理想情况下,我保持内存布局,只更改数组上的视图.
最后,如果它有助于从概念上考虑这一点,这基本上是 ndarray.flatten() 方法的变体,但使用形状块 (4, 4, 4)作为原子大小"如果你愿意.

So this does actually generate the right indexes, but it only allows you to access multiple blocks at once if they have the same index in the 0th and 1st axis, so no wrapping around. Ideally I would reshape this whole ndarray into an ndarray b with shape (4, 4, 32) and be ordered in such a way that b[:, :, :4] would return a[0:4, 0:4, 0:4], b[:, :, 4:12] returns an ndarray of shape (4, 4, 8) which contain a[0:4, 0:4, 4:8] and a[0:4, 4:8, 0:4] etc. I want this to be as fast as possible, so ideally, I keep the memory layout and just change the view on the array.
Lastly, if it helps to think about this conceptually, this is basically a variant of the ndarray.flatten() method but using blocks of shape (4, 4, 4) as "atomic size" if you will.

希望这足够清楚了!

推荐答案

有点不清楚你想要什么作为输出.你在找这个吗:

It is a bit unclear what you want as output. Are you looking for this:

from skimage.util.shape import view_as_windows
b = view_as_windows(a,(f,f,f),f).reshape(-1,f,f,f).transpose(1,2,3,0).reshape(f,f,-1)

@Paul 提出的类似结果(实际上我更喜欢这个答案):

suggested by @Paul with similar result (I prefer this answer in fact):

N = 8
b = a.reshape(2,N//2,2,N//2,N).transpose(1,3,0,2,4).reshape(N//2,N//2,N*4)

输出:

print(np.array_equal(b[:, :, 4:8],a[0:4, 0:4, 4:8]))
#True
print(np.array_equal(b[:, :, 8:12],a[0:4, 4:8, 0:4]))
#True
print(np.array_equal(b[:, :, 12:16],a[0:4, 4:8, 4:8]))
#True

这篇关于将 Numpy 数组重塑为形状 (n, n, n) 立方体的字典列表的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆