のんびりしているエンジニアの日記

ソフトウェアなどのエンジニア的な何かを書きます。

Pandasで特徴量取得する場合に使う操作をまとめてみた

Sponsored Links

皆さんこんにちは
お元気ですか。私は元気です。

分析は基本的にPythonを使って行います。(大体Pandasですが・・・)
Pandasを利用すると色々できます。が、ふとどうするんだっけ処理が増えていきました。

自分のメモがてらカテゴリを分けて記録に残したいと思います。
最後のほうは特徴量の作り方集になっています。

Kaggleで実際に使ったことがある処理も数多く掲載しました。
思いついたら随時、追加しようと思います。

準備

本コードは事前に「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長く使っていたので纏めてみると結構多くてびっくりです。
特徴量作成にまだまだ使えるので、ぜひ使ってみてください。