はじめに
この実験では、pandas ライブラリで疎データ構造を使用する方法について説明します。これは、大量のデータがあり、その大部分が同じ(ゼロや NaN など)場合に役立ち、メモリ内でより効率的に表現できます。SparseArray、SparseDtype、疎アクセサ、疎計算、および scipy 疎行列との相互作用について学びます。
VM のヒント
VM の起動が完了したら、左上隅をクリックして ノートブック タブに切り替え、Jupyter Notebook を使用して練習します。
場合によっては、Jupyter Notebook が読み込み終わるまで数秒待つ必要があります。Jupyter Notebook の制限により、操作の検証を自動化できません。
学習中に問題が発生した場合は、Labby にお問い合わせください。セッション後にフィードバックを提供してください。すぐに問題を解決いたします。
疎配列の作成
まず、疎配列を作成します。これは、疎な値の配列を効率的に格納するための pandas のデータ構造です。疎な値とは、大部分の値と同じであるため格納されない、冗長と考えられる値のことです。
## 必要なライブラリをインポート
import pandas as pd
import numpy as np
## ランダムな値を持つ numpy 配列を作成
arr = np.random.randn(10)
## いくつかの値を NaN に設定
arr[2:-2] = np.nan
## pandas を使って疎配列を作成
ts = pd.Series(pd.arrays.SparseArray(arr))
## 疎配列を出力
print(ts)
メモリ効率の確認
次に、疎データ構造を使用した場合のメモリ効率を確認します。大きな DataFrame を作成し、それを疎に変換してから、メモリ使用量を比較します。
## ランダムな値を持つ大きな DataFrame を作成
df = pd.DataFrame(np.random.randn(10000, 4))
## DataFrame の大部分を NaN に設定
df.iloc[:9998] = np.nan
## DataFrame を疎に変換
sdf = df.astype(pd.SparseDtype("float", np.nan))
## 高密度と低密度の DataFrame のメモリ使用量を確認
print('dense : {:0.2f} bytes'.format(df.memory_usage().sum() / 1e3))
print('sparse: {:0.2f} bytes'.format(sdf.memory_usage().sum() / 1e3))
SparseDtype の理解
SparseDtype は、非疎な値の dtype とスカラーの埋め値を格納します。dtype のみを渡すか、明示的な埋め値も渡すことで構築できます。
## SparseDtype を作成
print(pd.SparseDtype(np.dtype('datetime64[ns]')))
## 明示的な埋め値を持つ SparseDtype を作成
print(pd.SparseDtype(np.dtype('datetime64[ns]'), fill_value=pd.Timestamp('2017-01-01')))
疎アクセサの使用
疎データ固有の属性やメソッドを取得するには、.sparse アクセサを使用できます。
## 疎な値を持つ Series を作成
s = pd.Series([0, 0, 1, 2], dtype="Sparse[int]")
## 疎アクセサを使用
print(s.sparse.density)
print(s.sparse.fill_value)
疎計算の実行
NumPy の ufunc を SparseArray に適用し、結果として SparseArray を取得することができます。
## SparseArray を作成
arr = pd.arrays.SparseArray([1., np.nan, np.nan, -2., np.nan])
## NumPy の ufunc を適用
print(np.abs(arr))
疎と高密度の間の変換
データを疎から高密度に、またはその逆に簡単に変換できます。
## 疎から高密度に変換
print(sdf.sparse.to_dense())
## 高密度から疎に変換
dense = pd.DataFrame({"A": [1, 0, 0, 1]})
dtype = pd.SparseDtype(int, fill_value=0)
print(dense.astype(dtype))
scipy の疎行列との相互作用
最後に、scipy の疎行列から疎な値を持つ DataFrame を作成したり、その逆を行ったりすることができます。
## 必要なライブラリをインポート
from scipy.sparse import csr_matrix
## scipy を使って疎行列を作成
arr = np.random.random(size=(1000, 5))
arr[arr <.9] = 0
sp_arr = csr_matrix(arr)
## 疎行列から DataFrame を作成
sdf = pd.DataFrame.sparse.from_spmatrix(sp_arr)
## DataFrame を表示
print(sdf.head())
print(sdf.dtypes)
## 再び疎行列に変換
print(sdf.sparse.to_coo())
まとめ
この実験では、メモリ効率の良い格納と計算のために pandas で疎データ構造をどのように使用するかを学びました。SparseArray、SparseDtype を使用し、疎計算を行いました。また、高密度と疎の間でどのように変換するか、および scipy の疎行列とどのように相互作用するかを学びました。