2017-12-12 32 views
1

두 개의 드문 드문 한 배열이 (거의) 동일한 지 확인하고 싶습니다. 반면 NumPy와 배열을 위해 당신이 할 수 있습니다 :두 스파 스 배열이 (거의) 같은지 테스트하는 방법은 무엇입니까?

import numpy as np 

a = np.ones(200) 
np.testing.assert_array_almost_equal(a, a) 

이것은 내가 이해할 수있는 스파 스 배열, 작동하지 않습니다는 (두 배열의 크기와 관련된 작은 행렬 또는 오류에 대한 오류 AttributeError: ravel not found를 반환). 테스트 희소 매트릭스에 해당하는 scipy가 있습니까? 내 스파 스 행렬을 조밀 한 행렬로 변환하고 numpy 테스트 함수를 사용할 수는 있지만 때때로 (메모리/크기) 제약으로 인해 가능하지 않습니다. 예컨대 :

from scipy import sparse 

b = sparse.rand(80000,8000,density=0.01) 
type(b) # <class 'scipy.sparse.coo.coo_matrix'> 
c = b.toarray() # ValueError: array is too big; `arr.size * arr.dtype.itemsize` is larger than the maximum possible size. 

이 어떤지이 큰 scipy 배열을 테스트 할 수 있나요, 아니면 작은 샘플을 테스트해야합니까?

답변

2

공차 값 내에있을 수있는 배열에 0이 아닌 값이있는 것으로 가정하면 행, 열 인덱스 및 해당 값을 가져 와서 인덱스 간 정확한 일치를 찾을 수 있습니다. 값은 allclose()과 일치합니다.

따라서, 구현이 될 것이다 -

from scipy.sparse import find 

def allclose(A, B, atol = 1e-8): 

    # If you want to check matrix shapes as well 
    if np.array_equal(A.shape, B.shape)==0: 
     return False 

    r1,c1,v1 = find(A) 
    r2,c2,v2 = find(B) 
    index_match = np.array_equal(r1,r2) & np.array_equal(c1,c2) 

    if index_match==0: 
     return False 
    else: 
     return np.allclose(v1,v2, atol=atol) 

을 여기 find 기능을 대체 할 nonzerodata 방법과 다른입니다 -

def allclose_v2(A, B, atol = 1e-8): 
    # If you want to check matrix shapes as well 
    if np.array_equal(A.shape, B.shape)==0: 
     return False 

    r1,c1 = A.nonzero() 
    r2,c2 = B.nonzero() 

    lidx1 = np.ravel_multi_index((r1,c1), A.shape) 
    lidx2 = np.ravel_multi_index((r2,c2), B.shape) 

    sidx1 = lidx1.argsort() 
    sidx2 = lidx2.argsort() 

    index_match = np.array_equal(lidx1[sidx1], lidx2[sidx2]) 
    if index_match==0: 
     return False 
    else: 
     v1 = A.data 
     v2 = B.data   
     V1 = v1[sidx1] 
     V2 = v2[sidx2]   
     return np.allclose(V1,V2, atol=atol) 

을 우리는 몇몇 장소에서 단락은 그것을 더 속도를 수 . 성능면에서 나는 값이 다른 경우에만 더 집중하고 있습니다.

+1

만약'if index_match :'뒤에'np.allclose'를 넣고 싶을 수도 있습니다. 'v1'과'v2'가 다른 길이라면 에러를냅니다. –

+0

정확하게 이해한다면 행과 열 indeces가 동일하고 값이 가까운 지 비교할 것을 제안합니다. 나는 아이디어를 좋아하지만 find()가 예제에서 작동하는 방식을 보니 ​​stuggle하면 (오류가 발생 함) 사용하려고합니다. 비교 문에서 직접'A.row','A.col','A.data'를 사용하는 것과 동일합니까? – BartDur

+0

@BartDur 길이가 동일한 지 비교하기 위해 IF가 필요하다고 추측합니다. 편집 됨. – Divakar