2017-01-06 1 views
5

'scipy_sparse_csr_matrix'a '와 scipy_sparse_csr_matrix (boolean)'mask '가 두 개 있는데'a '요소를 0으로 설정하려면 마스크 요소 사실이다. scipy 스파 스 매트릭스에서 mask가 True이면 요소를 0으로 설정하는 효율적인 방법

>>>a 
<3x3 sparse matrix of type '<type 'numpy.int32'>' 
    with 4 stored elements in Compressed Sparse Row format> 
>>>a.todense() 
matrix([[0, 0, 3], 
     [0, 1, 5], 
     [7, 0, 0]]) 

>>>mask 
<3x3 sparse matrix of type '<type 'numpy.bool_'>' 
    with 4 stored elements in Compressed Sparse Row format> 
>>>mask.todense() 
matrix([[ True, False, True], 
     [False, False, True], 
     [False, True, False]], dtype=bool) 

예를

에 대한

은 그 때 나는 다음과 같은 결과를 얻을합니다.

>>>result 
<3x3 sparse matrix of type '<type 'numpy.int32'>' 
    with 2 stored elements in Compressed Sparse Row format> 
>>>result.todense() 
matrix([[0, 0, 0], 
     [0, 1, 0], 
     [7, 0, 0]]) 

나는

result = a - a.multiply(mask) 

또는

a -= a.multiply(mask) #I don't care either in-place or copy. 

같은 조작으로 그것을 할 수 있습니다하지만 위의 작업이 비효율적 생각합니다. 'a'와 'mask'의 실제 모양이 67,108,864 × 2,000,000이기 때문에 이러한 작업은 고사양 서버 (64 코어 Xeon CPU, 512GB 메모리)에서 몇 초가 걸립니다. 예를 들어, 'a'는 약 30,000,000 개가 아닌 요소이고 'mask'는 약 1,800,000 개가 아닌 0 개 요소이며, 위의 연산은 약 2 초 걸립니다.

더 효율적인 방법이 있습니까?

조건은 다음과 같습니다.

  1. a.getnnz()! = mask.getnnz()
  2. a.shape = mask.shape

감사합니다!

다른 방법은

a.data*=~np.array(mask[a.astype(np.bool)]).flatten();a.eliminate_zeros() #This takes twice the time longer than above method. 
+0

'a'와'마스크 '의'nnz'는 어떻게 비교됩니까? 게다가 같지 않아. 둘 다 동등하게 희박합니까? – hpaulj

+0

답변 해 주셔서 감사합니다. @hpaulj! 너를 혼동해서 미안해. 조건 1은 '마스크의 0이 아닌 (거짓) 요소의 수는 a의 요소 수와 다릅니다.'만을 의미합니다. – hiroto1228

답변

0

내 첫 인상이 증식 및 빼기 접근이 합리적인 한 점이다 (시도). 매우 자주 sparse 코드는 조밀 한 등가물이 더 직접적인 방법을 사용하더라도 일종의 곱셈 연산을 구현합니다. 행 또는 열에 대한 스파 스 합계는 1의 적절한 행 또는 열 행렬과 행렬 곱을 사용합니다. 행 또는 열 인덱싱조차도 행렬 곱셈을 사용합니다 (적어도 csr 형식).

매트릭스 속성 (data, indices, indptr)으로 직접 작업하여 작업을 향상시킬 수있는 경우가 있습니다. 그러나 그것은 많은 생각과 실험을 필요로합니다.

조밀 한 배열의 내 첫 번째 시도는

In [611]: a.A*~(mask.A) 
Out[611]: 
array([[0, 0, 0], 
     [0, 1, 0], 
     [7, 0, 0]], dtype=int32) 

것이다 그러나 희소 행렬에 not을하는 직접적인 방법이 없습니다. mask이 실제로 희박한 경우 ~mask이 표시되지 않습니다. 당신의 예에서 mask은 False 4 진정한 용어 및 5를 가지고, 그래서 조밀 한 버전은 잘 작동 :

In [612]: nmask=sparse.csr_matrix(~(mask.A)) 
In [615]: a.multiply(nmask) 
Out[615]: 
<3x3 sparse matrix of type '<class 'numpy.int32'>' 
    with 2 stored elements in Compressed Sparse Row format> 

CSR scipy matrix does not update after updating its values 0으로 스파 스 매트릭스의 대각선을 설정 탐구의 값을 설정할 수 있습니다 data 속성을 0으로 설정하고 마지막으로 eliminate_zeros을 지정하십시오.

In [628]: a2.eliminate_zeros() 
In [629]: a2 
Out[629]: 
<3x3 sparse matrix of type '<class 'numpy.int32'>' 
    with 2 stored elements in Compressed Sparse Row format> 
: -

다른 밀도 방법이 또한 sparse에서 작동

In [618]: a1=a.A 
In [619]: a1[mask.A]=0 

이다 앞의 질문에서 언급 한 바와 같이

In [622]: a2=a.copy() 
In [624]: a2[mask] 
Out[624]: matrix([[0, 3, 5, 0]], dtype=int32) 
In [625]: a2[mask]=0 
/usr/local/lib/python3.5/dist-packages/scipy/sparse/compressed.py:730: SparseEfficiencyWarning: Changing the sparsity structure of a csr_matrix is expensive. lil_matrix is more efficient. 
    SparseEfficiencyWarning) 
In [626]: a2 
Out[626]: 
<3x3 sparse matrix of type '<class 'numpy.int32'>' 
    with 6 stored elements in Compressed Sparse Row format> 

의 종류, 우리는 0을 제거 할 필요가

희박 경고에서 힌트를 얻으려면 lil 형식을 사용해보십시오.

In [638]: al=a.tolil() 
In [639]: al[mask] 
Out[639]: 
<1x4 sparse matrix of type '<class 'numpy.int32'>' 
    with 2 stored elements in LInked List format> 
In [640]: al[mask]=0 
In [641]: al 
Out[641]: 
<3x3 sparse matrix of type '<class 'numpy.int32'>' 
    with 2 stored elements in LInked List format> 

그것은 al[mask] 여전히 부족한 것을 흥미뿐만 ​​a[mask]는 조밀하다. 2 가지 형식은 서로 다른 색인 방법을 사용합니다.

낮은 수준의 희소성에서는 mask의 True (0이 아닌) 요소를 반복하여 해당 용어 인 a을 직접 0으로 설정할 필요가 있습니다.

이 방법의 상대적인 속도는 추측하지 않습니다. 현실적인 데이터를 테스트해야합니다.

+0

말하자면, 실제 행렬의 모양이 너무 크기 때문에 행렬에 ~을 적용 할 수 없습니다. 나는 마스크를 0으로 만들었지 만 1 분 넘게 걸렸다. 방금 .data/elimin_zeros를 사용하여 답을 얻으려는 아이디어가 있습니다 (마지막 질문에 추가하십시오). 저는 이것을 월요일에 실제 데이터로 시도 할 것입니다. 감사! – hiroto1228

+0

실제 데이터에서 새로운 방법을 시도했지만 곱하기 방법보다 두 배 더 오래 걸렸습니다. – hiroto1228

+0

나는 너무 놀랍지 않다. – hpaulj

관련 문제