カテゴリ変数を持つ大きなデータフレームがあります。カテゴリ変数の各値に起因するデータフレームのサブセットから値を取得し、これをリストのコレクションとして保存したいと思います(これは、提供するコード例でスパースベクトルを作成するために使用されます)。
私の現在の方法は、カテゴリ変数の各値を反復処理し、この値を持つデータフレームを選択してから、このサブデータフレームからリストを取得します。データフレームのループとサブデータフレームの作成という2つの理由で、かなり遅いと思います。
プロセスをスピードアップし、この種の一時データフレームのループを回避する方法を見つけたいと思います (コードで頻繁に行っていることがわかります)。私の現在のプロジェクトのスケール感を与えるために、5mil の観測で約 7k のカテゴリがあります。現在のワークフローを示すために、以下のコードを含めます。
データフレームのセットアップ:
import pandas as pd
c1=['a','b','c','d','e']*5
c2=[4,8,3,5,6]*6
c3=list(range(1,11))*3
df=pd.DataFrame(list(zip(c1,c2,c3)),columns=['catvar','weight','loc'])
データフレームのサブセットをループする関数:
from scipy.sparse import csr_matrix
def make_sparse_vectors(df,
loc_colname='loc',
weighting_colname='weight',
cat_colname='catvar',
):
# create list of ids:
id_list=list(df[cat_colname].unique())
# length of sparse vector:
vlength=max(df[loc_colname])+1
# loop to create sparse vectors:
sparse_vector_dict={}
for i in id_list:
df_temp=df[df[cat_colname]==i]
temp_loc_list=df_temp[loc_colname].tolist()
temp_weight=df_temp[weighting_colname].tolist()
temp_row_list=[0]*len(temp_loc_list)
sparse_vector_dict[i]=csr_matrix((temp_weight,(temp_row_list,temp_loc_list)),shape=(1,vlength))
return sparse_vector_dict
make_sparse_vectors(df)
戻り値:
{'a': <1x11 sparse matrix of type '<class 'numpy.intc'>'
with 2 stored elements in Compressed Sparse Row format>,
'b': <1x11 sparse matrix of type '<class 'numpy.intc'>'
with 2 stored elements in Compressed Sparse Row format>,
'c': <1x11 sparse matrix of type '<class 'numpy.intc'>'
with 2 stored elements in Compressed Sparse Row format>,
'd': <1x11 sparse matrix of type '<class 'numpy.intc'>'
with 2 stored elements in Compressed Sparse Row format>,
'e': <1x11 sparse matrix of type '<class 'numpy.intc'>'
with 2 stored elements in Compressed Sparse Row format>}
私が最も最適化できると思うコード スニペットは、一意の値をループして一時的なデータフレームを作成するポイントです。
for i in id_list:
df_temp=df[df[cat_colname]==i]
いくつかの考え:
- Pandas の groupby() 関数は理想的なように思えますが、ドキュメントでわかることから、主にデータフレームの次元を減らすために使用されます。場合によっては便利ですが、この問題には適用できません (私がプルしているリストは、合計でデータフレームと同じ次元になるため)
- マスキングは役立つかもしれませんが、ループを使用せずにこれを実現できるマスクを思いつきませんでした。