Pandasで特徴量取得する場合に使う操作をまとめてみた
皆さんこんにちは
お元気ですか。私は元気です。
分析は基本的にPythonを使って行います。(大体Pandasですが・・・)
Pandasを利用すると色々できます。が、ふとどうするんだっけ処理が増えていきました。
自分のメモがてらカテゴリを分けて記録に残したいと思います。
最後のほうは特徴量の作り方集になっています。
Kaggleで実際に使ったことがある処理も数多く掲載しました。
思いついたら随時、追加しようと思います。
- 準備
- ファイル操作
- テーブル操作
- カラム、テーブルの統計情報を取得する。
- 日付操作
- 2つ以上のDataFrameの結合操作
- 集計操作を使った特徴量作成
- 変数の変換を行う。
- Numpyへの変換を行う。
- 最後に
準備
本コードは事前に「import pandas as pd」を利用しています。
ファイルの操作、結合などを行うファイルを準備します。
ファイルの内容は次の通りです。
■df_example1.csv
名前 | 性別 | 年齢 |
太郎 | 男 | 21 |
二郎 | 男 | 30 |
三郎 | 男 | 21 |
四郎 | 男 | |
花子 | 女 | 14 |
■df_example2.csv
名前 | 部活動 |
太郎 | 陸上 |
二郎 | 野球 |
四郎 | 野球 |
花子 | 華道 |
■df_example3.csv
名前 | 性別 | 年齢 |
五郎 | 男 | 22 |
六郎 | 男 | 21 |
七郎 | 男 | 21 |
八郎 | 男 | 3 |
九子 | 女 | 14 |
■df_example4.csv
趣味 | 授業 |
データ分析 | 地理 |
ゲーム | 世界史 |
ゲーム | 理科 |
読書 | 国語 |
Neural Network | 数学 |
ファイル操作
読み込み
df1 = pd.read_csv("df_example1.csv") df2 = pd.read_csv("df_example2.csv") df3 = pd.read_csv("df_example3.csv") df4 = pd.read_csv("df_example4.csv") df = pd.read_csv("temp.tsv", separete="\t") # TSVファイル df = pd.read_excel("temp.xlsx") # Excelファイル
書き込み
df1.to_csv("temp_w.csv",index=False) # IndexがTrueの場合はIndexも出力される。大体は不要
テーブル操作
1行ごとに処理をする。
for index, row in df1.iterrows(): print (index, row)
複数列を取得する。
print (df1[["名前", "年齢"]]) # 名前 年齢 #0 太郎 21 #1 二郎 30 #2 三郎 21 #3 四郎 NAN #4 花子 14
選択操作
テーブル条件の指定
print (df1[df1["性別"] == "男"]) # 名前 性別 年齢 #0 太郎 男 21.0 #1 二郎 男 30.0 #2 三郎 男 21.0 #3 四郎 男 NaN
複数条件の指定
&で結合すれば、複数の条件を選択できる。(|を指定すればOR)
print (df1[(df1["性別"] == "男") & (df1["年齢"] > 25)]) # 名前 性別 年齢 # 1 二郎 男 30.0
NaNを埋める。
NaNになる値を埋めたいケースがあります。
print (df1.fillna(-1)) # 名前 性別 年齢 #0 太郎 男 21.0 #1 二郎 男 30.0 #2 三郎 男 21.0 #3 四郎 男 -1.0 #4 花子 女 14.0
カラム、テーブルの統計情報を取得する。
df1["年齢"].mean() # 出力は省略 df1["年齢"].median() # 出力は省略 df1["年齢"].max() # 出力は省略 df1["年齢"].min() # 出力は省略 df1.describe() # 年齢 #count 4.000000 #mean 21.500000 #std 6.557439 #min 14.000000 #25% NaN #50% NaN #75% NaN #max 30.000000
完全一致の列を発見し、除去する。
重複している列を発見します。重複しているカラムは必要がないことから
重複を調べ除去したいことがあります。
この除去には、pandasのdrop_duplicateを使います。
df.T.drop_duplicates().T
日付操作
日付から日などの情報を取得する。
特徴量を生成する際に日付から曜日などの特徴を取得したいケースがあります。
その日付から新しい特徴量を作成できます。
date = pd.date_range('2017-01-01 00:00', periods=1, freq='D')[0] print (date) # 2017-01-01 00:00:00 print (date.dayofweek) # 6 print (date.month, date.day, date.hour, date.minute) # 1 1 0 0
2つ以上のDataFrameの結合操作
内部結合
2つ以上のテーブルを結合する。RDBのjoinと同じ操作です。
print (pd.merge(df1, df2, how="inner", on="名前")) # 名前 性別_x 年齢 性別_y 部活動 # 0 太郎 男 21.0 男 陸上 # 1 二郎 男 30.0 男 野球 # 2 四郎 男 NaN 男 野球 # 3 花子 女 14.0 女 華道
外部結合
print (pd.merge(df1, df2, how="outer", on="名前")) # 名前 性別 年齢 部活動 #0 太郎 男 21.0 陸上 #1 二郎 男 30.0 野球 #2 三郎 男 21.0 NaN #3 四郎 男 NaN 野球 #4 花子 女 14.0 華道
2つの結合処理
Onを利用した結合をしない処理はpd.concatで可能です。
pd.concat([df3, df4], axis=0) #縦方向の結合 # 名前 性別 年齢 #0 太郎 男 21.0 #1 二郎 男 30.0 #2 三郎 男 21.0 #3 四郎 男 NaN #4 花子 女 14.0 #0 五郎 男 22.0 #1 六郎 男 21.0 #2 七郎 男 21.0 #3 八郎 男 3.0 #4 九子 女 14.0 pd.concat([df3, df4], axis=1) #横方向の結合 # 名前 性別 年齢 趣味 授業 #0 太郎 男 21.0 データ分析 地理 #1 二郎 男 30.0 ゲーム 世界史 #2 三郎 男 21.0 ゲーム 理科 #3 四郎 男 NaN 読書 国語 #4 花子 女 14.0 Neural Network 数学
集計操作を使った特徴量作成
結合したデータを使って、Group Byを利用して集計します。
例えば、2つ以上のカラムを利用して集計する場合に使います。
2つのカラムを組み合わせて統計を取り、特徴量にする場合
2つのカラムを組み合わせて統計を取り、それを特徴量にしたい場合があります。
その場合はgroupby reset_index, mergeを使います。
merged_df = pd.merge(df1, df2, how="outer", on="名前") mean = merged_df.groupby(["性別"]).mean() reset_mean = mean.reset_index() print(merged_df.merge(reset_mean, how="left", on="性別")) # 名前 性別 年齢_x 部活動 年齢_y #0 太郎 男 21.0 陸上 24.0 #1 二郎 男 30.0 野球 24.0 #2 三郎 男 21.0 NaN 24.0 #3 四郎 男 NaN 野球 24.0 #4 花子 女 14.0 華道 14.0
変数の変換を行う。
カテゴリカルな変数
ダミー変数に変換し、結果を結合する。
dummies_df = pd.get_dummies(df1["性別")) pd.concat([df1, dummies_df], axis=1) # 名前 性別 年齢 女 男 #0 太郎 男 21.0 0.0 1.0 #1 二郎 男 30.0 0.0 1.0 #2 三郎 男 21.0 0.0 1.0 #3 四郎 男 NaN 0.0 1.0 #4 花子 女 14.0 1.0 0.0
ラベル変数にし、結果を取得する。
from sklearn.preprocessing import LabelEncoder df1["性別"] = LabelEncoder().fit_transform(df1["性別"]) # 名前 性別 年齢 #0 太郎 1 21.0 #1 二郎 1 30.0 #2 三郎 1 21.0 #3 四郎 1 NaN #4 花子 0 14.0
Numpyへの変換を行う。
私は以下の2つのどちらかで変換を行います。大体np.arrayで実行しています。
df1.as_matrix() np.array(df1)
最後に
pandas長く使っていたので纏めてみると結構多くてびっくりです。
特徴量作成にまだまだ使えるので、ぜひ使ってみてください。