블록 대각선 행렬 크기 (N, N) 인 정사각형 2D 배열이 있다고 가정 해 보겠습니다. 각 블록은 (말) (N_b, N_b)입니다. 이들 블록 중 일부는 단지 0 (예 : (N_b, N_b) 0의 행렬)입니다. 이 블록을 (N_b, N_b) 0 배열이없는 행렬로 남겨두고 싶습니다.2d numpy 배열에서 0 인 사각형 부분 행렬 제거
또한, 나는 또한 모든 요소가 같은 장소
모든 I에있는 요구 사항이 "압착"매트릭스 중 하나를 수행하고 (제로 패딩) 원래 크기로 확장합니다 싶습니다 요구 루프와 많은 회계를 생각할 수 있습니다. 나는 희소 행렬을 사용하게되어 기쁩니다. 그러나 그것은 훨씬 더 복잡하게 보입니다.
("스퀴즈") 문제의 첫 번째 부분은이 방식으로 수행 될 수있다 : 여기
import numpy as np
import scipy.sparse as sp
A = np.random.randn(3,3)*5
B = A*0.
M = np.array(sp.block_diag ((A, B, A, A, A, B, A)).todense())
n_b = A.shape[0]
n_blocks = M.shape[0]/n_b
block_locs = []
nonzero_blocks = []
for this_block in xrange (n_blocks):
if np.all(M[n_b*this_block:(this_block+1)*n_b, n_b*this_block:(this_block+1)*n_b] != 0):
nonzero_blocks.append (M[n_b*this_block:(this_block+1)*n_b, n_b*this_block:(this_block+1)*n_b])
block_locs.append (this_block)
squeezed_M = sp.block_diag (nonzero_blocks).tolil()
blocky = []
this_squeeze_block = 0
for this_block in xrange(n_blocks):
if this_block in block_locs:
blocky.append (squeezed_M[this_squeeze_block*n_b:(this_squeeze_block+1)*n_b,
this_squeeze_block * n_b:(this_squeeze_block + 1) * n_b])
this_squeeze_block += 1
else:
blocky.append (np.zeros((n_b, n_b)))
A_big = sp.block_diag(blocky).todense()
print np.allclose(M, A_big)
가 상기 압착 된 버전 (하단) (제로 블록, 상단) 원래 매트릭스의 플롯이다 : 문제의 대칭성을 이용
편집 더 간결한 방법이 될 수있다 :
import numpy as np
import scipy.sparse as sp
import matplotlib.pyplot as plt
# First create a big matrix with gaps
n_b = 3
A = np.random.randn(n_b,n_b)*5
B = A*0.
M = sp.block_diag ((A, B, A, A, A, B, A))
# Select the rows which are not all zeros
no_zeros = np.any(np.array((M != 0).todense()), axis=1)
n_blocks = no_zeros.sum()
# where's the meat?
meat = np.outer (no_zeros, no_zeros)
# We need to use a lil matrix to address by a boolean array
# And then we just reshape
A_squeeze = M.tolil()[meat].reshape((n_blocks, n_blocks))
reco = sp.lil_matrix (M.shape)
reco[np.outer(no_zeros, no_zeros)]=A_squeeze.todense().ravel()
np.allclose(M.todense(), reco.todense())
plt.subplot(1,2,1)
plt.spy(M)
plt.subplot(1,2,2)
plt.spy(A_squeeze)
블록 매트릭스 또는 블록 대각 매트릭스로 시작 하시겠습니까? – James
@James 블록 대각선입니다. – Jose
블록 대각선 행렬에는 모든 대각선이 아닌 모든 요소에 0이 있습니다. 그러면 대각선에서 0을 제거하기 만하면됩니까? http://mathworld.wolfram.com/BlockDiagonalMatrix.html – James