2016-11-14 7 views
0

は私がto_sparseどのように2つの値を「まばらにする」ことができますか?

s.to_sparse(fill_value=0).memory_usage() 

4080 

を使用してこれを "sparsify" することができます。しかし、私は整数のみの2種類がありs

n = 1000 
s = pd.Series([0] * n + [1] * n, dtype=int) 

s.memory_usage() 

8080 

パンダシリーズを検討してください。私は2回疎らにすることができると思うだろう。これを行う方法はありますか?

+1

私は 'スパース格納し、そのデータをpd'方法がわかりません。私はこれらの数字から、すべての1のインデックスを収集すると推測しています。 'scipy.sparse matrix'は、インデックスとデータ(すべて1)を格納します。 scipyのバージョンは、メモリと計算速度において多くの利点を見るために1%の希薄さが必要です。 – hpaulj

+2

'' s.astype(np.uint8).to_sparse() 'はどうなっていますか? – MaxU

+0

@MaxUは、メモリフットプリントを確実に削減します。しかし、ゼロと1の位置だけを追跡すれば、それをさらに落とす可能性があります。 – piRSquared

答えて

3

あなたはscipyでこれをタグ付けされているので、私はscipy.sparse行列がどのようなものであるかを紹介します:それはn/2要素と2列毎にarrn要素を置き換えた

In [31]: n=100 
In [32]: arr=np.array([[0]*n+[1]*n],int) 
In [33]: M=sparse.csr_matrix(arr) 
In [34]: M.data 
Out[34]: 
array([1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 
     1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 
     1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 
     1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 
     1, 1, 1, 1, 1, 1, 1, 1], dtype=int32) 
In [35]: M.indices 
Out[35]: 
array([100, 101, 102, 103, 104, 105, 106, 107, 108, 109, 110, 111, 112, 
     113, 114, 115, 116, 117, 118, 119, 120, 121, 122, 123, 124, 125, 
     126, 127, 128, 129, 130, 131, 132, 133, 134, 135, 136, 137, 138, 
     139, 140, 141, 142, 143, 144, 145, 146, 147, 148, 149, 150, 151, 
     152, 153, 154, 155, 156, 157, 158, 159, 160, 161, 162, 163, 164, 
     165, 166, 167, 168, 169, 170, 171, 172, 173, 174, 175, 176, 177, 
     178, 179, 180, 181, 182, 183, 184, 185, 186, 187, 188, 189, 190, 
     191, 192, 193, 194, 195, 196, 197, 198, 199], dtype=int32) 
In [36]: M.indptr 
Out[36]: array([ 0, 100], dtype=int32) 

intuint8に置き換えても、M.indicesの配列はまだint32になります。

あなたのpandasバージョンがメモリ使用量の半分を持っているという事実は、単にインデックスを格納していることを示唆しており、dataの部分がすべて1であることに注意してください。しかし、それはちょうど推測です。

あなたはどれくらいのスパリフィケーションを期待していますか?

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

http://pandas.pydata.org/pandas-docs/stable/sparse.html

この例では、パンダのように見える 'RUN' 圧縮のいくつかの並べ替えを実施している。

In [4]: sts 
Out[4]: 
0 0.469112 
1 -0.282863 
2   NaN 
3   NaN 
4   NaN 
5   NaN 
6   NaN 
7   NaN 
8 -0.861849 
9 -2.104569 
dtype: float64 
BlockIndex 
Block locations: array([0, 8], dtype=int32) 
Block lengths: array([2, 2], dtype=int32) 

2つのブロックがそれぞれ長さ2であることが確認されています。まだ4つの非塗りつぶし値をいくつかの配列に格納する必要があります。

CSRスパース等価(行アレイ用):フィル値はブロックで発生した場合

In [1052]: arr=np.random.rand(10) 
In [1053]: arr[2:-2]=0 
In [1055]: M=sparse.csr_matrix(arr) 
In [1056]: M 
Out[1056]: 
<1x10 sparse matrix of type '<class 'numpy.float64'>' 
    with 4 stored elements in Compressed Sparse Row format> 
In [1057]: M.data 
Out[1057]: array([ 0.37875012, 0.73703368, 0.7935645 , 0.22948213]) 
In [1058]: M.indices 
Out[1058]: array([0, 1, 8, 9], dtype=int32) 
In [1059]: M.indptr 
Out[1059]: array([0, 4], dtype=int32) 

パンダのバージョンは、よりコンパクトであるかもしれません。しかし、私は疑問を持っています。

0   1.0 
1   1.0 
2   NaN 
3   NaN 
4   NaN 
5   NaN 
6   NaN 
7   NaN 
8   1.0 
9   1.0 

は同じブロックを生成します。私はそれが同じ1.0の値を識別しようとしているという証拠を見ておらず、それらの値を値に加えて数として保存しています。

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

@MaxU回答に基づいて、あなたのDSの店1000年1's、およびそれらの値が格納されている場所、それを伝える2つの素子アレイ。

In [56]: sp.memory_usage() 
Out[56]: 1080 

In [57]: sp.sp_index 
Out[57]: 
BlockIndex 
Block locations: array([1000]) 
Block lengths: array([1000]) 

nonfill値が大きいの実行中に発生する限り、block配列は小さくなります。あなたはシリーズから、これらの1000の値を通じ散乱場合しかし、あなたは私がcsrレイアウトやパンダブロックの間のマッピングを想像することができ、実質的に

​​

ブロックの数を掛けると思いますが、詳細を働いていません。csrのレイアウトは、行と列の明確なコンセプトで2次元アレイで動作するようになっています。スパースなデータフレームのように見えるのは、スパースなシリーズオブジェクトだけです。

https://stackoverflow.com/a/38157234/901925

===================はscipyのダウンロードスパース行列にスパースデータフレーム値からマッピングする方法を示します。各列(データ系列)に対して、sp_values,fill_value,sp_indexを使用します。

pandas/pandas/sparse/scipy_sparse.pyには、scipy sparseとデータ系列の間の相互作用のコードがあります。

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

kind='integer' produces sparse structure more like scipy.sparse`:

:デフォルト blockとその

In [62]: n=5; s=pd.Series([0]*5+[1]*5, dtype=int) 
In [63]: ss=s.to_sparse(fill_value=0, kind='integer') 
In [64]: ss 
Out[64]: 
0 0 
1 0 
2 0 
3 0 
4 0 
5 1 
6 1 
7 1 
8 1 
9 1 
dtype: int32 
IntIndex 
Indices: array([5, 6, 7, 8, 9]) 

コントラスト

dtype: int32 
BlockIndex 
Block locations: array([5]) 
Block lengths: array([5]) 

と同等の列スパース行列がで構築することができます。

In [89]: data=ss.values 
In [90]: data=ss.sp_values 
In [91]: rows=ss.sp_index.indices 
In [92]: cols=np.zeros_like(rows) 
In [93]: sparse.csr_matrix((data,(rows,cols))) 
Out[93]: 
<10x1 sparse matrix of type '<class 'numpy.int32'>' 
    with 5 stored elements in Compressed Sparse Row format> 

to_cooメソッドがありますが、これはより複雑なpd.MultiIndexオブジェクト(なぜ?)でのみ機能します。

+0

私はそれを正確な理由のためにscipyとタグ付けしました。いつも学ぶ;-) – piRSquared

+0

私は希薄化の実際の測定にはあまり関心がありませんが、むしろその背後にあるアイデアです。私はパンダに戻って、ゼロと注文の性質を混乱させる必要があります。他の洞察を集めることができます。 Thx – piRSquared

+1

それは価値があるので、 'scipy.sparse'モジュールはMATLABの疎な実装や他のスパースな線形代数の仕事をモデルにしていました。したがって、 'csr'のようなフォーマットは、行列積や大規模な線形方程式解などに最適化されています。例えば大きな有限差分と有限要素問題。 – hpaulj

3

Pandas documentationは言う:

現在、float64int64bool dtypesがサポートされています。

それではbool値にあなたのシリーズを変換してみましょう:

In [53]: s.memory_usage() 
Out[53]: 8080 

In [54]: s.to_sparse().memory_usage() 
Out[54]: 4080 

In [55]: sp = s.astype(bool).to_sparse() 

In [56]: sp.memory_usage() 
Out[56]: 1080 

In [57]: sp.sp_index 
Out[57]: 
BlockIndex 
Block locations: array([1000]) 
Block lengths: array([1000]) 
+0

ブールキャストキーです...ありがとう – Boud

+0

@Boud、ありがとう!しかし、[@ hpauljの解決策](http://stackoverflow.com/a/40595971/5741205)を見てください。これは、同じデータに対して1080に対して56バイトしかかかりません! – MaxU

関連する問題