1. ホーム
  2. python

[解決済み] データフレーム全体に対するpandas.factorize

2022-02-11 15:55:33

質問

pandas.factorize は、入力値を列挙型またはカテゴリ変数としてエンコードします。

しかし、データフレームの多くの列を簡単かつ効率的に変換するにはどうしたらよいでしょうか。逆マッピングのステップはどうでしょうか?

例 このデータフレームには "type 2" のような文字列値を持つ列があり、これを数値に変換し、場合によっては後で元に戻したいと思っています。

解決方法は?

を使用することができます。 apply 必要であれば factorize を各カラムごとに設定します。

df = pd.DataFrame({'A':['type1','type2','type2'],
                   'B':['type1','type2','type3'],
                   'C':['type1','type3','type3']})

print (df)
       A      B      C
0  type1  type1  type1
1  type2  type2  type3
2  type2  type3  type3

print (df.apply(lambda x: pd.factorize(x)[0]))
   A  B  C
0  0  0  0
1  1  1  1
2  1  2  1

同じ文字列の値には同じ数値が必要な場合。

print (df.stack().rank(method='dense').unstack())
     A    B    C
0  1.0  1.0  1.0
1  2.0  2.0  3.0
2  2.0  3.0  3.0


一部の列に対してのみ関数を適用する必要がある場合は、サブセットを使用します。

df[['B','C']] = df[['B','C']].stack().rank(method='dense').unstack()
print (df)
       A    B    C
0  type1  1.0  1.0
1  type2  2.0  3.0
2  type2  3.0  3.0

を使った解決策 factorize :

stacked = df[['B','C']].stack()
df[['B','C']] = pd.Series(stacked.factorize()[0], index=stacked.index).unstack()
print (df)
       A  B  C
0  type1  0  0
1  type2  1  2
2  type2  2  2

を経由して翻訳し直すことが可能です。 map によって dict での重複を削除する必要がある場合。 drop_duplicates :

vals = df.stack().drop_duplicates().values
b = [x for x in df.stack().drop_duplicates().rank(method='dense')]

d1 = dict(zip(b, vals))
print (d1)
{1.0: 'type1', 2.0: 'type2', 3.0: 'type3'}

df1 = df.stack().rank(method='dense').unstack()
print (df1)
     A    B    C
0  1.0  1.0  1.0
1  2.0  2.0  3.0
2  2.0  3.0  3.0

print (df1.stack().map(d1).unstack())
       A      B      C
0  type1  type1  type1
1  type2  type2  type3
2  type2  type3  type3