2016-09-07 26 views
1

(正規化された)スパース隣接行列とそれぞれの行列行のラベルのリストが与えられました。いくつかのノードは別のサニタイズ関数によって削除されているため、行列にNaNを含む行がいくつかあります。これらの行を見つけて、とそれぞれのラベルを削除したいと思います。ここで私が書いた機能は次のとおりです。scipyスパース行列のナノ行を削除する

def sanitize_nan_rows(adj, labels): 
    # convert to numpy array and keep dimension 
    adj = np.array(adj, ndmin=2) 

    for i, row in enumerate(adj): 
     # check if row all nans 
     if np.all(np.isnan(row)): 
      # print("Removing nan row label in %s" % i) 
      # remove row index from labels 
      del labels[i] 
    # remove all nan rows 
    adj = adj[~np.all(np.isnan(adj), axis=1)] 
    # return sanitized adj and labels_clean 
    return adj, labels 

labelsは、単純なPythonのリストであるとadjは(タイプ<class 'numpy.float64'>の要素を含む)タイプ<class 'scipy.sparse.lil.lil_matrix'>があり、実行の両方

adj, labels = nx.attr_sparse_matrix(infected, normalized=True) 

の結果である私は、次のエラーを取得する:

--------------------------------------------------------------------------- 
TypeError         Traceback (most recent call last) 
<ipython-input-503-8a404b58eaa9> in <module>() 
----> 1 adj, labels = sanitize_nans(adj, labels) 

<ipython-input-502-ead99efec677> in sanitize_nans(adj, labels) 
     6  for i, row in enumerate(adj): 
     7   # check if row all nans 
----> 8   if np.all(np.isnan(row)): 
     9    print("Removing nan row label in %s" % i) 
    10    # remove row index from labels 

TypeError: ufunc 'isnan' not supported for the input types, and the inputs could not be safely coerced to any supported types according to the casting rule ''safe'' 

は、だから私は、scipyのダウンロードNaNをnumpyのはNaNを異なっていたと思いました。その後、私は疎な行列を数が少ない配列に変換しようとしました(行列には約40kの行と列があるため、RAMにフラッディングのリスクがあります)。しかし、それを実行すると、エラーは同じままです。ループの内側type(row)はまだ私の質問は、この問題を解決する方法ですとなる、より良いアプローチがあるかどうか<class 'scipy.sparse.lil.lil_matrix'>

を出力としては、np.array()呼び出しがちょうど疎行列を包み、それを変換しなかったようです仕事が終わった。私はnumpyとscipy(networkxで使われている)にはかなり新しいので、私は説明を感謝します。ありがとうございました!

EDIT:

--------------------------------------------------------------------------- 
MemoryError        Traceback (most recent call last) 
<ipython-input-519-8a404b58eaa9> in <module>() 
----> 1 adj, labels = sanitize_nans(adj, labels) 

<ipython-input-518-44201f4ff35c> in sanitize_nans(adj, labels) 
     1 def sanitize_nans(adj, labels): 
----> 2  adj = adj.toarray() 
     3 
     4  for i, row in enumerate(adj): 
     5   # check if row all nans 

/usr/lib/python3/dist-packages/scipy/sparse/lil.py in toarray(self, order, out) 
    348  def toarray(self, order=None, out=None): 
    349   """See the docstring for `spmatrix.toarray`.""" 
--> 350   d = self._process_toarray_args(order, out) 
    351   for i, row in enumerate(self.rows): 
    352    for pos, j in enumerate(row): 

    /usr/lib/python3/dist-packages/scipy/sparse/base.py in_process_toarray_args(self, order, out) 
    697    return out 
    698   else: 
--> 699    return np.zeros(self.shape, dtype=self.dtype, order=order) 
    700 
    701 

MemoryError: 

だから明らかに私はRAMを節約するために、疎行列に固執する必要があります:hpauljが提案されているものに変換を変更した後、私は、MemoryErrorを取得しています。

+0

スパース行列は密な配列ではありません。 'adj.data'と' adj.rows'を見てください。 'lil'マトリックスの場合、これはlistのオブジェクト配列であり、配列の1行あたり1組のサブリストです。 – hpaulj

+0

'adj.A'または' adj.toarray() 'は配列を生成します – hpaulj

+0

あなたのクイック返信ありがとう!私はあなたの提案された変更と私の結果に従って質問を編集しました。 (変換ラインを 'adj = adj.toarray()'に変更しました) – dmuhs

答えて

0

Iは、サンプルアレイ作る場合:

In [328]: A=np.array([[1,0,0,np.nan],[0,np.nan,np.nan,0],[1,0,1,0]]) 
In [329]: A 
Out[329]: 
array([[ 1., 0., 0., nan], 
     [ 0., nan, nan, 0.], 
     [ 1., 0., 1., 0.]]) 

In [331]: M=sparse.lil_matrix(A) 

このリル疎行列を2列に格納されている:あなたの機能で

In [332]: M.data 
Out[332]: array([[1.0, nan], [nan, nan], [1.0, 1.0]], dtype=object) 
In [333]: M.rows 
Out[333]: array([[0, 3], [1, 2], [0, 2]], dtype=object) 

、どの行も中段かかわらず、削除されませんスパース行列の中にはnanしか含まれていません。

In [334]: A[~np.all(np.isnan(A), axis=1)] 
Out[334]: 
array([[ 1., 0., 0., nan], 
     [ 0., nan, nan, 0.], 
     [ 1., 0., 1., 0.]]) 

私はnanためMの行をテストし、唯一の(0以外)nanが含まれているものを特定することができました。しかし、おそらく私たちが保持したいものを集めるほうが簡単でしょう。 M

In [346]: ll = [i for i,row in enumerate(M.data) if not np.all(np.isnan(row))] 
In [347]: ll 
Out[347]: [0, 2] 
In [348]: M[ll,:] 
Out[348]: 
<2x4 sparse matrix of type '<class 'numpy.float64'>' 
    with 4 stored elements in LInked List format> 
In [349]: _.A 
Out[349]: 
array([[ 1., 0., 0., nan], 
     [ 1., 0., 1., 0.]]) 

行のリストですが、np.isnan(row)は配列に変換し、それがアレイテストです行います。

+0

これは多くの助けになりました!私はそれに応じて自分のコードを適合させました。私は 'adj = adj [ll、:] [:, ll]'でスライスして、隣接行列の対称性を保っていました。しかし、このインデックスまたは 'll'インデックスのリストのいずれかが私のRAMにあふれているようです。これを行うにはより効率的な方法がありますか?行列は、およそ40kの行と列を持ちます。 – dmuhs

+0

'lil'の行の索引付けは効率的ですが、列を削除するのは面倒なので、各部分配列を変更する必要があります。列がどのようになっているかを見るにはコードを参照する必要があります。 – hpaulj

関連する問題