機械学習の事前準備に使うPandasの機能
機械学習を行う前の事前処理として、よく使うPandasの機能をまとめています。
さらに詳細なコードはGitHubのコードを参考にしてください。
import文
とりあえず読み込んでおきたいライブラリ
import numpy as np import numpy.random as random import scipy as sp from pandas import Series,DataFrame import pandas as pd import matplotlib.pyplot as plt import matplotlib as mpl import seaborn as sns %matplotlib inline import sklearn %precision 3
ファイルの読み込みと保存
CSVファイルの読み込み
data = pd.read_csv("data.csv")
read_csv()関数の引数は多く存在する。
主要な引数として、 sep :区切り文字の指定、headr=Noneでヘッダーの有無、encodingでエンコーディングの指定などができる。
エクセルで作成したCSVファイルは文字化けします。その際にはencoding=’SHIFT-JIS’を使用。それでもうまくいかない時はencoding=’cp932’を試して見ると良い。
タブ区切りのCSVファイルについては、pd.read_table()関数を使う。
エクセルファイルの読み込み
data = pd.read_excel('data.xlsx', sheet_name='sample')
CSVファイルの保存
行のindexが不要の場合は引数でindex=Falseを指定する。
文字コードの指定は引数の encoding=’shift_jis’などとして、出力する際の文字コード。’utf-8′, ‘shift_jis’, ‘euc_jp’ などを指定することができます。デフォルト値は ‘utf-8’
data.to_csv('./data.csv')
データの確認
何行何列のデータか確認
data.shape
結果
(205, 26)
「有効データ数」「データ型」「メモリ使用量」などの総合的な情報を表示
data.info
結果
bound method DataFrame.info of symboling normalized-losses make … city-mpg highway-mpg price
0 3 ? alfa-romero … 21 27 13495
1 3 ? alfa-romero … 21 27 16500
2 1 ? alfa-romero … 19 26 16500
3 2 164 audi … 24 30 13950
4 2 164 audi … 18 22 17450
.. … … … … … … …
200 -1 95 volvo … 23 28 16845
201 -1 95 volvo … 19 25 19045
202 -1 95 volvo … 18 23 21485
203 -1 95 volvo … 26 27 22470
204 -1 95 volvo … 19 25 22625
[205 rows x 26 columns]
変数別の基本統計量の確認
data.describe()
結果
symboling | while-base | length | width | height | |
---|---|---|---|---|---|
count | 205.000000 | 205.000000 | 205.000000 | 205.000000 | 205.000000 |
mean | 0.834146 | 98.756585 | 174.049268 | 65.907805 | 53.724878 |
std | 1.245307 | 6.021776 | 12.337289 | 2.145204 | 2.443522 |
min | -2.000000 | 86.600000 | 141.100000 | 60.300000 | 47.800000 |
25% | 0.000000 | 94.500000 | 166.300000 | 64.100000 | 52.000000 |
50% | 1.000000 | 97.000000 | 173.200000 | 65.500000 | 54.100000 |
75% | 2.000000 | 102.400000 | 183.100000 | 66.900000 | 55.500000 |
max | 3.000000 | 120.900000 | 208.100000 | 72.300000 | 59.800000 |
先頭からの表示
data.head()
結果
horsepower | width | height | |
---|---|---|---|
196 | 114 | 67.2 | 56.2 |
53 | 68 | 64.2 | 54.1 |
0 | 111 | 64.1 | 48.8 |
97 | 69 | 63.8 | 53.5 |
112 | 95 | 68.4 | 56.7 |
後ろからの表示
data.tail()
結果
horsepower | width | height | |
---|---|---|---|
70 | 123 | 71.7 | 56.3 |
198 | 162 | 67.2 | 56.2 |
120 | 68 | 63.8 | 50.6 |
50 | 68 | 64.2 | 54.1 |
178 | 161 | 67.7 | 52.0 |
列に複数の同じ値がある場合、それぞれの値の数を調べる
trans['列名'].value_counts()
欠損値処理
欠損値の数の確認
data.isnull().sum()
欠損値の削除
data = data.dropna(subset=["kcal"])
欠損値を平均値で埋める
data = data['kcal'].fillna(data['kcal'].mean())
欠損値を0にしてそれ以外の文字列を1にする
data['event'] = pd.isnull(data['event']).map(lambda x : 0 if x else 1 )
欠損値に他の列の値を利用
train['Age'] = train['Age'].fillna(train['Fare_Age'])
さらに他の列の値に何らか処理を加えることも可能
train['Age'] = train['Age'].fillna(train['Fare'].map(lambda x: 50 if x > 70 else 20))
教師データの分離と削除
教師データ分離
y = train_base["y"]
教師データ削除(説明変数作成)
X = train_base.drop('y',axis=1)
ダミー変数作成
ダミー変数作成
get_dummies関数を使うと、カテゴリ変数を簡単に数値に置き換えることができます。
デフォルトでは欠損値があれば、その値は除外されます。
引数 dummy_na=True とすることで欠損値を含めることもできる。欠損値は全ての値が0になります。
X = pd.get_dummies(X[["week","temperature"]])
2値のカテゴリ変数を数値に変換
説明変数の値がカテゴリ変数で入っている場合の数値化
data['flg'] = data['y'].map(lambda x: 1 if x == 'on' else 0)
複数のカテゴリ変数をそのまま数値化する これ、結構使える
説明変数の値が数値ではなく、何らかの文字列の場合、複数の数値に変換する場合は
pd.factorize関数を使用します。
欠損値は-1にしてくれるなど至れり尽せりの関数です。
data = {'name':['Nakajima','Hanazawa','Hama','Isono'], 'id':[1,2,3,4], 'age':[48,30,28,51], 'weight':[60,78,64,58], 'size':['S','M','L',np.nan]} data_f5 = pd.DataFrame(data) data_f5['size_num'], _ = pd.factorize(data_f5['size']) data_f5
結果
name | id | age | weight | size | size_num | |
---|---|---|---|---|---|---|
0 | Nakajima | 1 | 48 | 60 | S | 0 |
1 | Hanazawa | 2 | 30 | 78 | M | 1 |
2 | Hama | 3 | 28 | 64 | L | 2 |
3 | Isono | 4 | 51 | 58 | NaN | -1 |
複数のカテゴリ変数をそのまま数値化する factorize関数を使わない方法
pandasのcategory型の仕組みを活用した方法です。
trainデータに’Sex’という項目があるとします。
文字列を数値化したデータを’sex_num’の列を新たに作成して挿入する方法です。
取得した’Sex’列の値をカテゴリ型に変更することで、実現しています。
train['sex_num'] = train['Sex'].astype('category').values.codes
標準化
from sklearn.preprocessing import StandardScaler scaler = StandardScaler() X_standerd = scaler.fit_transform(X)
学習用データとテストデータの分離
ホールドアウト法
X_train,X_test,y_train,y_test = train_test_split(X,y,test_size=0.5,random_state=0)
列の値の取得
ユニークな値の取得
unique()関数を使用するとユニークな値を取得できます。
対象の列「fruit」には[‘Apple’,’Orange’,’Apple’,’Apple’,’Apple’,’Orange’,’Apple’,’Apple’]が入っているとします。
df['fruit'].unique()
結果
array([‘Apple’, ‘Orange’], dtype=object)
複数の値を含めた数を知りたい場合は、value_counts()関数を使います。
df['fruit'].value_counts()
結果
Apple 6
Orange 2
Name: fruit, dtype: int64
ある列の値を条件判定しておいて、Trueの行の別の列の値の平均をとる
次のようなDataFrame型のデータがあるとします。
sizeがMの行のweightの値の平均をとるコードです。
name | id | age | weight | size | size_num | |
---|---|---|---|---|---|---|
0 | Nakajima | 1 | 48 | 60 | S | 0 |
1 | Hanazawa | 2 | 30 | 78 | M | 1 |
2 | Hama | 3 | 28 | 64 | L | 2 |
3 | Isono | 4 | 51 | 58 | NaN | -1 |
4 | Anago | 5 | 56 | 48 | L | 2 |
5 | Isasaka | 6 | 81 | 52 | M | 1 |
DataFrameのデータが入った変数名を data_pd とします。
次のコードで対象の平均値が算出されます。
data_pd[data_pd['size']=='M']["weight"].mean()
結果
65.0
PandasからNumpyに変換とその逆
Pandas形式のデータをNumpy形式にする方法
Pandasデータをdfとすると次のようにvaluesプロパティで取得できます。
なお、列名を取得したい場合は、columnsプロパティで取得し、行名はindexプロパティで取得します。
my_data = df.values my_column = df.columns my_index = df.index
Numpy形式のデータをPandas形式にする方法
DataFrameを作成するだけです。
df = pd.DataFrame(data=data,columns=columns)
要素の頻度(出現回数)
要素の頻度(出現回数)が取得できます。
value_counts()は、ユニークな要素の値がindex、その出現個数がdataとなるpandas.Seriesを返す。
デフォルトでは降順となります。引数ascending=Trueとすると昇順にソートさます。
引数sort=Falseとするとソートされません。
円グラフを描くときは、引数ascending=Trueにすると見やすくなります。
円グラフとして活用例
x = train['age_group'].value_counts(ascending=True) label_index = train['age_group'].value_counts(ascending=True).index plt.figure(figsize=(5,5)) plt.pie(x, labels= label_index, startangle=90, labeldistance=1,rotatelabels=True) plt.show()
ビニング処理(ビン分割)
例えば、年齢を一定の年齢層にビン分割したい場合、cut()関数を使います。
pandas.cut()関数では、第1引数に元データとなる一次元配列(Pythonのリストやnumpy.ndarray, pandas.Series)、第2引数にビン分割設定を指定します。
できること
- 最大値と最小値の間を等間隔で分割
- 境界値を指定して分割
- 境界値のリストを取得: 引数retbins
- 左右どちらのエッジを含めるか指定: 引数right
- ラベルを指定: 引数labels
- 境界値の精度(小数点以下の桁数)を指定: 引数precision
age_bins =[0,10,30,50,70,90] pd.cut(train['Age'],age_bins)
結果
0 (10, 30]
1 (30, 50]
2 (10, 30]
3 (30, 50]
4 (30, 50]
…
886 (10, 30]
887 (10, 30]
888 (10, 30]
889 (10, 30]
890 (30, 50]
Name: Age, Length: 891, dtype: category
Categories (5, interval[int64]): [(0, 10] < (10, 30] < (30, 50] < (50, 70] < (70, 90]]
コメントを投稿するにはログインしてください。