2017-05-25 5 views
0

EDIT:それでも2つのデータセットが異なる列を持っているときに動作答えを探して!メモリ効率的なホットエンコードパンダ

私は両方のデータセットで特定の列をホットエンコードしようとしています。列は異なるデータセットで異なる値を持つため、単純なホットエンコーディングは異なる列につながります。目的の結果:

DATASET A       
col1 col2 target     
a  1  1     
b  2  2     
c  2  3     
d  3  3     

DATASET B       
col1 col2 target     
d   2  2     
h   4  3     
g   2  2     
b   3  3     

After encoding col 1:       

New dataset A       

col2 target a b c d h g 
1   1 1 0 0 0 0 0 
2   2 0 1 0 0 0 0 
2   3 0 0 1 0 0 0 
3   3 0 0 0 1 0 0 

New dataset B       

col2 target a b c d h g 
2   2 0 0 0 1 0 0 
4   3 0 0 0 0 1 0 
2   2 0 0 0 0 0 1 
3   3 0 1 0 0 0 0 

次の実装は機能しますが、メモリが非常に効率が悪く、MemoryErrorsのためにコンピュータが頻繁にクラッシュします。

def hot_encode_column_in_both_datasets(column_name,df,df2,sparse=True,drop_first = True): 
     print("Hot encoding {} for both datasets".format(column_name)) 
     cols_in_df_but_not_in_df2 = set(df[column_name]).difference(set(df2[column_name])) 
     cols_in_df2_but_not_in_df = set(df2[column_name]).difference(set(df[column_name])) 

     dummy_df_to_concat_to_df = pd.DataFrame(0,index=df.index,columns = cols_in_df2_but_not_in_df) 
     dummy_df_to_concat_to_df2 = pd.DataFrame(0,index=df2.index,columns = cols_in_df_but_not_in_df2) 

     dummy_df_to_concat_to_df = dummy_df_to_concat_to_df.to_sparse() 
     dummy_df_to_concat_to_df2 = dummy_df_to_concat_to_df2.to_sparse() 

     encoded = pd.get_dummies(df[column_name],sparse=sparse) 
     encoded = pd.concat([encoded,dummy_df_to_concat_to_df],axis = 1) 
     encoded_2 = pd.get_dummies(df2[column_name],sparse=sparse) 
     encoded_2 = pd.concat([encoded_2,dummy_df_to_concat_to_df2],axis = 1) 

     encoded_df = pd.concat([df,encoded],axis=1) 
     encoded_df2 = pd.concat([df2,encoded_2],axis=1) 

     del encoded_df[column_name] 
     del encoded_df2[column_name] 

     return encoded_df,encoded_df2 

これを行うより良い方法はありますか?

ありがとうございました! :)

+0

画像などのデータやコードを入れないで下さい。そうすることで、例のデータを手作業で入力する必要があるため、助けてくれる人には迷惑をかけることになります。 –

+0

@HaleemurAli謝罪、私はそれがよりきれいに見えると思った。今修正しよう! :) – Wboy

+0

あなたの例からは、データセットを1つのホットエンコードに追加してから、インデックスまたはフラグ変数に基づいて事実を分離するように見えます。これがうまくいかない理由はありますか? –

答えて

1

あなたはCategory型の列をエンコードし、get_dummies方法などの方法を、パンダ事実を利用したい列は、そのようなカラムは、特定のデータフレームでは観察されない値を有することができるという点を作ることができます。これにより、2つのDataFrameのマージ/ジョインを避けることができ、1つのDataFrameに表示される列が存在するかどうかに関わらず、どちらの列にも表示されません。文書番号Categorical columns

私はパンダのv0.20.1を使用しています。

import numpy as np 
import pandas as pd 
import string 

dfa = pd.DataFrame.from_dict({ 
    'col1': np.random.choice([ltr for ltr in string.ascii_lowercase[:4]], 5) 
    , 'col2b': np.random.choice([1, 2, 3], 5) 
    , 'target': np.random.choice([1, 2, 3], 5) 
    }) 

dfb = pd.DataFrame.from_dict({ 
    'col1': np.random.choice([ltr for ltr in string.ascii_lowercase[2:8]], 7) 
    , 'col2b': np.random.choice(['foo', 'bar', 'baz'], 7) 
    , 'target': np.random.choice([1, 2, 3], 7) 
    }) 

DFA:

col1 col2b target 
0 b  3  1 
1 d  3  3 
2 b  3  3 
3 a  2  3 
4 c  1  3 

DFB:

col1b = set(dfb.col1.unique()) 
col1a = set(dfa.col1.unique()) 
combined_cats = list(col1a.union(col1b)) 

許容値を定義します。

col1 col2b target 
0 g foo  2 
1 c bar  1 
2 h baz  3 
3 c baz  3 
4 d baz  3 
5 d bar  2 
6 d foo  3 

は2つのデータフレームで観察col1の値の和集合を探します0123の同一の両方のデータフレームの:

# Use these statements if `col1` is a 'Category' dtype. 
# dfa['col1'] = dfa.col1.cat.set_categories(combined_cats) 
# dfb['col1'] = dfb.col1.cat.set_categories(combined_cats) 
# Otherwise, use these statements. 
dfa['col1'] = dfa.col1.astype('category', categories=combined_cats) 
dfb['col1'] = dfb.col1.astype('category', categories=combined_cats) 

newdfa = pd.get_dummies(dfa, columns=['col1']) 
newdfb = pd.get_dummies(dfb, columns=['col1']) 

newdfa:

col2b target col1_g col1_b col1_c col1_d col1_h col1_a 
0  3  1  0  1  0  0  0  0 
1  3  3  0  0  0  1  0  0 
2  3  3  0  1  0  0  0  0 
3  2  3  0  0  0  0  0  1 
4  1  3  0  0  1  0  0  0 

newdfb:

col2b target col1_g col1_b col1_c col1_d col1_h col1_a 
0 foo  2  1  0  0  0  0  0 
1 bar  1  0  0  1  0  0  0 
2 baz  3  0  0  0  0  1  0 
3 baz  3  0  0  1  0  0  0 
4 baz  3  0  0  0  1  0  0 
5 bar  2  0  0  0  1  0  0 
6 foo  3  0  0  0  1  0  0 
1

あなたの説明に基づいて、これは単に1つのホットエンコーディング前にデータフレームを追加することによって行うことができます。

combined = a.append(b).reset_index(drop=True) 
combinedDummies = pd.get_dummies(combined, columns=['col1']) 

newA = combinedDummies.iloc[0:a.shape[0]] 
newB = combinedDummies.iloc[a.shape[0]:] 

newA 
# col2 target col1_a col1_b col1_c col1_d col1_g col1_h 
# 0 1 1 1 0 0 0 0 0 
# 1 2 2 0 1 0 0 0 0 
# 2 2 3 0 0 1 0 0 0 
# 3 3 3 0 0 0 1 0 0 


newB 
# col2 target col1_a col1_b col1_c col1_d col1_g col1_h 
# 4 2 2 0 0 0 1 0 0 
# 5 4 3 0 0 0 0 0 1 
# 6 2 2 0 0 0 0 1 0 
# 7 3 3 0 1 0 0 0 0 
+0

あなたはそうです!どのように私はそれを逃しましたか?ありがとうございました! :) – Wboy

+0

ちょっと気付いた、2つのデータセットにいくつかの異なる列がある場合、これはうまくいきません。 – Wboy

+0

右。概念的には、ダミー変数を作成するためにすべての列が必要なわけではありません。各データセットから2つの関連する列を追加するだけで、インデックスを削除することはできません。どのデータセットに属しているかを示すフラグ変数を追加します。その後、フラグとインデックスに基づいて事実の後に他の変数をマージすることができます。 –