0

カテゴリ変数を持つ大きなデータフレームがあります。カテゴリ変数の各値に起因するデータフレームのサブセットから値を取得し、これをリストのコレクションとして保存したいと思います(これは、提供するコード例でスパースベクトルを作成するために使用されます)。

私の現在の方法は、カテゴリ変数の各値を反復処理し、この値を持つデータフレームを選択してから、このサブデータフレームからリストを取得します。データフレームのループとサブデータフレームの作成という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() 関数は理想的なように思えますが、ドキュメントでわかることから、主にデータフレームの次元を減らすために使用されます。場合によっては便利ですが、この問題には適用できません (私がプルしているリストは、合計でデータフレームと同じ次元になるため)
  • マスキングは役立つかもしれませんが、ループを使用せずにこれを実現できるマスクを思いつきませんでした。
4

1 に答える 1