2016-10-14 1 views
2

私はcrsスパース行列の一部に値を割り当てたい(私は高価だと知っていますが、私のプロジェクトでは問題ありません)。 私は、疎な行列の一部にfloat変数を割り当てようとしましたが、最初は機能しません。しかし、私が「例外」で全く同じことをしても、完璧に動作します。最初の「try:」でスパース行列の一部にデータを割り当てることができないのはなぜですか?

次に、疎な行列のdtypeとその一部を調べようとしました。何らかの理由でそれらが異なっています。行列全体のデータ型はfloat16ですが、行列の一部にはfloat32 dtypeがあります。ここで

は両方の問題のための小さな例です:

from scipy.sparse import csr_matrix 
import numpy as np 

frame = csr_matrix((10, 10),dtype=np.float16) 

print "================\n================ Part 1\n================" 
print "Let's assign a value to part of the sparse matrix:" 
try: 
    frame[0:3,0:3] = np.float16(0.6) 
    print "The first attempt worked!" 
except: 
    print "The first attempt didn't work" 

print "let's try again :" 

try: 
    frame[0:3,0:3] = np.float16(0.6) 
    print "The second attempt worked!" 
except: 
    print "The second attempt didn't work" 

print "================\n================ Part 2\n================" 
print "Let's check the datatype:" 
print "Frame dtype is:",; print frame.dtype 
print "Part-of-frame dtype is",; print frame[0:3,0:3].dtype 

、ここではその結果です:

================ 
================ Part 1 
================ 
Let's assign a value to part of the sparse matrix: 
The first attempt didn't work 
let's try again : 
The second attempt worked! 
================ 
================ Part 2 
================ 
Let's check the datatype: 
Frame dtype is: float16 
Part-of-frame dtype is float32 

はまだ私がスパース行列の一部にnp.float32を割り当てようとしました、そして私が得ました同じ行動。誰かが何が起きているのか説明できますか?

+0

私にとっては両方とも試行しますが、最初は 'SparseEfficiencyWarning'を与えます。 'scipy'のどのバージョンがありますか?私は0.16.1を使用しています。 – user6758673

+0

オープンな 'except'は悪い考えです。予期しないエラーが隠されます。特にデバッグするときに、エラーの性質を知りたい場合は、それを隠さないでください。 – hpaulj

+0

@ user6758673私はバージョン0.18.0を使用しています – Yugi

答えて

0

短い回答 - 問題はnp.float16です。通常32または64のフロートを貼り付けます。

(0.17単位)

===============================

まず作業ケース

In [334]: M=sparse.csr_matrix((5,5),dtype=np.float) 
In [335]: M[:3,:3]=0.6 
/usr/lib/python3/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 [336]: M.A 
Out[336]: 
array([[ 0.6, 0.6, 0.6, 0. , 0. ], 
     [ 0.6, 0.6, 0.6, 0. , 0. ], 
     [ 0.6, 0.6, 0.6, 0. , 0. ], 
     [ 0. , 0. , 0. , 0. , 0. ], 
     [ 0. , 0. , 0. , 0. , 0. ]]) 
In [338]: M.data 
Out[338]: array([ 0.6, 0.6, 0.6, 0.6, 0.6, 0.6, 0.6, 0.6, 0.6]) 

もう一度割り当てても、スパース性の警告は表示されません。私はあなたのDTYPEを使用する場合

は今、私は、スパース性の警告を取得するだけでなく、とValueError(あなたのジェネリックexceptがいることを隠した):

In [339]: M=sparse.csr_matrix((5,5),dtype=np.float16) 
In [340]: M[:3,:3]=np.float16(0.6) 
/usr/lib/python3/dist-packages/scipy/sparse/compressed.py:730: SparseEfficiencyWarning: Changing the sparsity structure of a csr_matrix is expensive. lil_matrix is more efficient. 
    SparseEfficiencyWarning) 
--------------------------------------------------------------------------- 
ValueError        Traceback (most recent call last) 
<ipython-input-340-aaecba748069> in <module>() 
----> 1 M[:3,:3]=np.float16(0.6) 

/usr/lib/python3/dist-packages/scipy/sparse/compressed.py in __setitem__(self, index, x) 
    654    return 
    655   i, j = self._swap((i.ravel(), j.ravel())) 
--> 656   self._set_many(i, j, x.ravel()) 
    657 
    658  def _setdiag(self, values, k): 

/usr/lib/python3/dist-packages/scipy/sparse/compressed.py in _set_many(self, i, j, x) 
    738    j = j[mask] 
    739    j[j < 0] += N 
--> 740    self._insert_many(i, j, x[mask]) 
    741 
    742  def _insert_many(self, i, j, x): 

/usr/lib/python3/dist-packages/scipy/sparse/compressed.py in _insert_many(self, i, j, x) 
    805    # TODO: only sort where necessary 
    806    self.has_sorted_indices = False 
--> 807    self.sort_indices() 
    808 
    809   self.check_format(full_check=False) 

/usr/lib/python3/dist-packages/scipy/sparse/compressed.py in sort_indices(self) 
    1039   if not self.has_sorted_indices: 
    1040    fn = _sparsetools.csr_sort_indices 
-> 1041    fn(len(self.indptr) - 1, self.indptr, self.indices, self.data) 
    1042    self.has_sorted_indices = True 
    1043 

ValueError: Output dtype not compatible with inputs. 

私はちょうどcsrに変換しようとした場合、私は同じエラーを取得します濃密:

In [346]: M=sparse.csr_matrix((5,5),dtype=np.float16) 
In [347]: M.A 
--------------------------------------------------------------------------- 
ValueError        Traceback (most recent call last) 
<ipython-input-347-bdd665fbe1b0> in <module>() 
----> 1 M.A 

/usr/lib/python3/dist-packages/scipy/sparse/base.py in __getattr__(self, attr) 
    511  def __getattr__(self, attr): 
    512   if attr == 'A': 
--> 513    return self.toarray() 
    514   elif attr == 'T': 
    515    return self.transpose() 

/usr/lib/python3/dist-packages/scipy/sparse/compressed.py in toarray(self, order, out) 
    938  def toarray(self, order=None, out=None): 
    939   """See the docstring for `spmatrix.toarray`.""" 
--> 940   return self.tocoo(copy=False).toarray(order=order, out=out) 
    941 
    942  ... 
ValueError: Output dtype not compatible with inputs. 

だから、問題は割り当てと、それdtypeの取り扱いではありません。これはバグのように見えますが、このdtypeを使用しないことで回避できます。

そしてlil行列もこのDTYPEに問題があります。変換の中でいくつかの点で

In [348]: M=sparse.lil_matrix((5,5),dtype=np.float16) 
In [349]: M[:3,:3]=np.float16(0.6) 
... 
KeyError: (dtype('int32'), dtype('float16')) 

を、指定されたDTYPEは保存されていません。

しかし、なぜ最初にfloat16を使用しますか? float32とfloat64は通常のnumpy浮動小数点数です。

でも、私は成功しnp.float16行列を作成するときに、そのDTYPEが最もまばらな操作中に保存されていません。

In [374]: M=sparse.csr_matrix(np.arange(9).reshape(3,3), dtype=np.float16) 
In [375]: M.data 
Out[375]: array([ 1., 2., 3., 4., 5., 6., 7., 8.], dtype=float16) 
In [376]: 
In [376]: M 
Out[376]: 
<3x3 sparse matrix of type '<class 'numpy.float16'>' 
    with 8 stored elements in Compressed Sparse Row format> 

In [377]: M.A # same error converting to dense 
... 
ValueError: Output dtype not compatible with inputs. 

In [378]: M.T  # dtype kept during transpose 
Out[378]: 
<3x3 sparse matrix of type '<class 'numpy.float16'>' 
    with 8 stored elements in Compressed Sparse Column format> 

DTYPEは、乗算またはインデックスに保存されていません。ほとんどの場合、コンパイルされた行列乗算コードは32と64(通常のC浮動小数点数と複素数)で書かれ、16ではなく書かれます。

In [379]: M*M 
Out[379]: 
<3x3 sparse matrix of type '<class 'numpy.float32'>' 
    with 9 stored elements in Compressed Sparse Row format> 
In [380]: M[0,:] 
Out[380]: 
<1x3 sparse matrix of type '<class 'numpy.float32'>' 
    with 2 stored elements in Compressed Sparse Row format> 

ドキュメントを約float16を警告している場合、私は知らないが、私はそれがほとんど役に立たないと思います。

+1

私が作業している行列が非常に大きいので、私はおそらくメモリの小さなビットを保存するためにfloat16に行くつもりだった。違いはわずか2バイトなので、私はそれを忘れてしまいます。とにかくありがとうございます – Yugi

+0

Btw、あなたは質問がより良いタイトルを持っているべきだと思うなら(あなたが課題からfloat16ではないと言ったので)あなたが望むようにそれを編集してください。 – Yugi

関連する問題