パンダデータフレームでカテゴリデータを変換する


101

このタイプのデータを含むデータフレームがあります(列が多すぎます)。

col1        int64
col2        int64
col3        category
col4        category
col5        category

列は次のようになります:

Name: col3, dtype: category
Categories (8, object): [B, C, E, G, H, N, S, W]

次のように、列のすべての値を整数に変換したい:

[1, 2, 3, 4, 5, 6, 7, 8]

私はこれによって1つの列についてこれを解決しました:

dataframe['c'] = pandas.Categorical.from_array(dataframe.col3).codes

今、私は私のデータフレームに2つの列を持っています-古いものcol3と新しいものでc、古い列を削除する必要があります。

それは悪い習慣です。それは機能しますが、私のデータフレームには多くの列があり、手動で実行したくありません。

これはどのようにしてpythonicで巧妙に行われますか?

回答:


163

まず、Categorical列を数値コードに変換するには、以下を使用してこれを簡単に実行できますdataframe['c'].cat.codes
さらに、を使用して、データフレーム内の特定のdtypeを持つすべての列を自動的に選択することができますselect_dtypes。このように、上記の操作を複数の自動的に選択された列に適用できます。

最初にサンプルデータフレームを作成します。

In [75]: df = pd.DataFrame({'col1':[1,2,3,4,5], 'col2':list('abcab'),  'col3':list('ababb')})

In [76]: df['col2'] = df['col2'].astype('category')

In [77]: df['col3'] = df['col3'].astype('category')

In [78]: df.dtypes
Out[78]:
col1       int64
col2    category
col3    category
dtype: object

次にを使用select_dtypesして列を選択し、.cat.codesこれらの各列に適用すると、次の結果が得られます。

In [80]: cat_columns = df.select_dtypes(['category']).columns

In [81]: cat_columns
Out[81]: Index([u'col2', u'col3'], dtype='object')

In [83]: df[cat_columns] = df[cat_columns].apply(lambda x: x.cat.codes)

In [84]: df
Out[84]:
   col1  col2  col3
0     1     0     0
1     2     1     1
2     3     2     0
3     4     0     1
4     5     1     1

14
カテゴリコードとカテゴリ文字列値の間のマッピングを取得する簡単な方法はありますか?
Allan Ruin

5
df['col2'].cat.categoriesたとえば、次のように使用でき ます。
ogrisel

13
これがにNaN一意にマッピングされることを懸念している人に指摘-1
quietContest

2
2つのライナーが大好きです;)
Jose A

カテゴリーが順序付けられている(序数)場合、によって返される数値コードはcat.codes、シリーズに表示されるものとは異なる場合があります。
パルペリー


20

余分な列を作成して後でそれを削除することだけが問題である場合は、最初から新しい列を使用してください。

dataframe = pd.DataFrame({'col1':[1,2,3,4,5], 'col2':list('abcab'),  'col3':list('ababb')})
dataframe.col3 = pd.Categorical.from_array(dataframe.col3).codes

完了です。今のようにCategorical.from_array廃止されました、使用してCategorical直接

dataframe.col3 = pd.Categorical(dataframe.col3).codes

インデックスからラベルへのマッピングも必要な場合は、同じためのさらに良い方法があります

dataframe.col3, mapping_index = pd.Series(dataframe.col3).factorize()

以下を確認してください

print(dataframe)
print(mapping_index.get_loc("c"))

11

ここでは、複数の列を変換する必要があります。したがって、私が使用した1つのアプローチは..

for col_name in df.columns:
    if(df[col_name].dtype == 'object'):
        df[col_name]= df[col_name].astype('category')
        df[col_name] = df[col_name].cat.codes

これにより、すべての文字列/オブジェクトタイプの列がカテゴリに変換されます。次に、カテゴリの各タイプにコードを適用します。


3

データセットデータのCのカテゴリデータを変換するには、次の操作を行う必要があります。

from sklearn.preprocessing import LabelEncoder 
labelencoder= LabelEncoder() #initializing an object of class LabelEncoder
data['C'] = labelencoder.fit_transform(data['C']) #fitting and transforming the desired categorical column.

1

@ Quickbeam2k1、以下を参照-

dataset=pd.read_csv('Data2.csv')
np.set_printoptions(threshold=np.nan)
X = dataset.iloc[:,:].values

sklearnの使用 ここに画像の説明を入力してください

from sklearn.preprocessing import LabelEncoder
labelencoder_X=LabelEncoder()
X[:,0] = labelencoder_X.fit_transform(X[:,0])

3
なぜあなたは以前の答えを正さなかったのですか?驚いたことに、labelencoder定義のfit_transform代わりに今使用しtransform_fitていて修正しました。なぜ使うのiloc[:,:]?これは役に立たない。画像の背後にある理由は何ですか?あなたが私と@theGtknerdを証明したかったのなら、あなたは失敗しました。
Quickbeam2k1 2017

1

私がしていることは、私がreplace大切にしていることです。

このような-

df['col'].replace(to_replace=['category_1', 'category_2', 'category_3'], value=[1, 2, 3], inplace=True)

このようにして、col列にカテゴリ値がある場合、それらは数値に置き換えられます。


0

特定の列について、順序を気にしない場合は、これを使用します

df['col1_num'] = df['col1'].apply(lambda x: np.where(df['col1'].unique()==x)[0][0])

順序が気になる場合は、リストとして指定し、これを使用してください

df['col1_num'] = df['col1'].apply(lambda x: ['first', 'second', 'third'].index(x))
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.