我希望能够以某种方式重新排序numpy数组,以便有效地处理tile。
我得到了什么:
>>> A = np.array([[1,2],[3,4]]).repeat(2,0).repeat(2,1)
>>> A # image like array
array([[[1, 1, 2, 2],
[1, 1, 2, 2]],
[[3, 3, 4, 4],
[3, 3, 4, 4]]])
>>> A.reshape(2,2,4)
array([[[1, 1, 2, 2],
[1, 1, 2, 2]],
[[3, 3, 4, 4],
[3, 3, 4, 4]]])
我想要的是什么:如何获得X:
>>> X
array([[[1, 1, 1, 1],
[2, 2, 2, 2]],
[[3, 3, 3, 3],
[4, 4, 4, 4]]])
这可能没有慢速python循环吗?
奖励:从X转换回A
Bago指出了一个我错过的类似问题:Creating a 4D view on 2D array to divide it into cells of fixed size
为什么一切都麻烦?能够做类似的事情:
>>> X[X.sum(2)>12] -= 1
>>> X
array([[[1, 1, 1, 1],
[2, 2, 2, 2]],
[[3, 3, 3, 3],
[3, 3, 3, 3]]])
编辑:解决方案:
# MIT - License
import numpy as np
def tile_reorder(A, t):
"""reshape and transpose quadratic array for easy access to quadratic tiles of size t"""
l = A.shape[0] / t
X = A.reshape((l, t, l, t))
X = X.transpose([0, 2, 1, 3])
return X
def tile_reorder_reverse(X):
l = X.shape[0] * X.shape[2]
A = X.transpose([0, 2, 1, 3])
A = A.reshape((l, l))
return A
if __name__ == "__main__":
A = np.array([[1,2,3],[3,4,5],[6,7,8]]).repeat(4,0).repeat(4,1)
print "A:\n", A, "\n\n"
print "A_tiled:\n", tile_reorder(A,4), "\n\n"
print "A_tiled_reversed:\n", tile_reorder_reverse(tile_reorder(A,4)), "\n\n"
X = tile_reorder(A,4)
X[X.sum((2)).sum(2)>63,:,:] += 10
B = tile_reorder_reverse(X)
print "B_processed:\n", B, "\n\n"
答案 0 :(得分:3)
你想要这样的东西:
>>> X = A.reshape(2,2,2,2)
>>> X = X.transpose([0,2,1,3])
>>> X = X.reshape((2,2,-1))
>>> X
array([[[1, 1, 1, 1],
[2, 2, 2, 2]],
[[3, 3, 3, 3],
[4, 4, 4, 4]]])
>>> B = X.reshape((2,2,2,2))
>>> B = B.transpose([0,2,1,3])
>>> B = B.reshape((2,2,-1))
>>> B
array([[[1, 1, 2, 2],
[1, 1, 2, 2]],
[[3, 3, 4, 4],
[3, 3, 4, 4]]])
答案 1 :(得分:1)
我认为你只是在查看数组的错误部分。以下应该做你想做的事。
>>> X[(X.sum(2)>12),:] -= 1
>>> X
array([[[1, 1, 1, 1],
[2, 2, 2, 2]],
[[3, 3, 3, 3],
[3, 3, 3, 3]]])
回到原来的顺序有点复杂。我相信你可以将下面的代码修改为一个名为get_back()
的函数,或者你不必一直重用它。
import numpy as np
X = np.asarray([[[1,1,1,1],[2,2,2,2]],[[3,3,3,3],[4,4,4,4]]])
print X
# Make the change to the array
# Note that I make the change to +=1 so we can indeed see that
# the reshaping worked by looking for the 5's.
X[(X.sum(2)>12),:] += 1
(M,N,P) = X.shape; # Number of tiles is MxN
orig_i = 2; orig_j = 2; # (Original rows/cols in a tile).
orig = (orig_i, orig_j) # Define as a tuple for convenience.
hstacks = []
for ii in range(M):
hstacks.append(X[ii,0,:].reshape(orig))
for jj in range(1,N):
hstacks[-1] = np.hstack(( hstacks[-1], X[ii,jj,:].reshape(orig) ))
orig_array = hstacks[0]
for kk in range(1,len(hstacks)):
orig_array = np.vstack(( orig_array, hstacks[kk] ))
# Print to confirm that it worked.
print orig_array
我得到以下内容:
>>> [[[1 1 1 1]
[2 2 2 2]]
[[3 3 3 3]
[4 4 4 4]]]
>>> [[1 1 2 2]
[1 1 2 2]
[3 3 5 5]
[3 3 5 5]]
为了测试,我尝试了更大的瓷砖图案,它给出了正确的结果。请注意,我使用函数get_back()
来封装上面的代码,我只是在平铺维度参数中硬编码到函数中。真的,他们应该是输入参数。
>>> X = np.asarray([[[1,1,1,1],[2,2,2,2],[3,3,3,3]],
[[4,4,4,4],[5,5,5,5],[6,6,6,6]]])
>>> X
array([[[1, 1, 1, 1],
[2, 2, 2, 2],
[3, 3, 3, 3]],
[[4, 4, 4, 4],
[5, 5, 5, 5],
[6, 6, 6, 6]]])
>>> get_back(X)
array([[1 1 2 2 3 3]
[1 1 2 2 3 3]
[4 4 5 5 6 6]
[4 4 5 5 6 6]])