随時更新
リンク
文字列処理
NAとInf処理
演算処理
削除処理
作成処理
変更処理
EDA
PyplotとSeaborn
出力処理
特徴量生成とエンコーディング
numpy arrayとlist
ファイルの読み書き
その他
文字列処理#
特殊文字の除去###
65%,78%...85%の%を取り除きたい
# 例1:
# r'\%'のところはpythonの正規化
df['a'] = df['a'].str.replace(r'%', '')
# 例2:
# 2020年1月1日を 2020/1/1 に変えたいとき
df['date'] = df['date'].str.replace(r'[年,月]', '/')
df['date'] = df['date'].str.replace(r'[日]', '')
特殊文字の置き換え###
appleかorangeかlemonの値はfruitsに置き換えたい
df['title'] = df['title'].str.replace(r'apple|orange|lemon', 'fruits')
日付から年・月・日を取り出す###
date = '12/01/02'
result = date.split('/')
print(result)
# ちなみに特徴量も作れる。
df[['year','month','date']] = df['date'].str.split('/', expand=True)
結果
['12', '01', '02']
列内の要素に特定の文字があるか否かを確かめる###
例えばforでループを回して列内を一つ一つチェックすることもできる。
# thousandsかmillionという文字が列の0番目の行に入っている場合
if '文字1' in df['volume'].iloc[0]:
#何かする
elif '文字2'in df['volume'].iloc[0]:
#何かする
特定の文字が入っている行だけを列内から抽出する###
new_df = df[df['a'].str.contains("文字")]
参照:http://pandas.pydata.org/pandas-docs/stable/user_guide/text.html
もし特定の列に特定の文字が含まれていたら文###
もし特定の列に特定の文字が含まれていたら、その文字を含んでいる行に何かをする。
if df['bas_toho1'].str.contains('徒歩').any():
do something
違う文字列に対して違う値を割り振る###
dct = {
'Miss':1,
'Ms':1,
'Mr':2,
}
train['title'] = 0
test['title'] = 0
for key, value in dct.items():
train.loc[train[train['Name'].str.contains(key,regex=False)].index,'title'] = value
test.loc[test[test['Name'].str.contains(key,regex=False)].index, 'title'] = value
NAとInf処理#
N/Aを数える###
print(df['levelplan'].isna().sum())
N/Aを埋める###
df.fillna(0,inplace=True)
df['a'].fillna(df['a'].mode()[0],inplace=True)
# 複数の時。inplaceだとfillnaしないので注意
df[['a', 'b']] = df[['a','b']].fillna(-1)
# NAを他の特徴量の値で埋める
# Ageの列でNaNとなっている行をfill_ageの列の値で埋める
train_test['Age'] = train_test['Age'].fillna(train_test['fill_age'])
NAの詳細カウント###
特徴(Column)毎にどれくらい紛失データがあるのかをランキングで出力
array = np.array([[1,2,3],[4,np.nan,6],[7,np.nan,np.nan]])
df_train = pd.DataFrame(array, columns=['a','b','c'])
total = df_train.isnull().sum().sort_values(ascending=False)
percent = (df_train.isnull().sum()/df_train.isnull().count()).sort_values(ascending=False)
missing_data = pd.concat([total, percent], axis=1, keys=['Total', 'Percent'])
print(missing_data.head(3))
結果
# 列 #紛失データ数 #紛失データの割合
Total Percent
b 2 0.666667
c 1 0.333333
a 0 0.000000
finiteの詳細カウント###
total = np.isfinite(train_X["label_5"]).sum().sort_values(ascending=False)
percent = (np.isfinite(train_X["label_5"]).sum()/np.isfinite(train_X["label_5"]).count()).sort_values(ascending=False)
finite_data = pd.concat([total, percent], axis=1, keys=['Total', 'Percent'])
print(finite_data)
inf除去###
df = df.replace([np.inf, -np.inf], np.nan)
NaNが入っている列をリスト形式で出力する###
print(df.columns[df.isna().any()].tolist())
NaNが入っている行だけを抽出する###
train = train[train.isnull().any(axis=1)]
演算処理#
列の掛け算###
df['number'] = df['number']*100
df['number'] *=100
一部のインデックスの列を演算する###
for i in range(segments):
train_y.loc[i, 'a'] = df['a'].iloc[i*149999]
列の順番を変更###
dfの列の順番がグチャグチャなので並び替えたい
列の順番 first,third,secondからfirst,second,thirdに直す
df = df[['first', 'second', 'third']]
削除処理#
無駄な特徴量を除去する###
features = [c for c in train_df.columns if c not in ['ID_code', 'target']]
df = df[features]
特定の行を削除###
df = pd.DataFrame(np.array([1,2,3]))
# 最初のインデックスの行を削除
df.drop([1], inplace=True)
# 複数のインデックスの行を削除
df.drop([1,2], inplace=True)
# ラストの行を削除
df.drop(df_train.tail(1).index,inplace=True)
#インデックスがラベル名の場合
# df.drop('label',axis=1,inplace=True)
# 条件付き
# df.drop(df[(df['col1'] < 60) & (df1['col1'] > 40)].index, inplace=True)
特定の列を削除###
df.drop('a', axis=1, inplace=True)
# 複数列の削除
df.drop(['a','b'], inplace=True)
列の重複除去###
df.drop_duplicates('column_1',inplace=True)
2つのコラムで同じ値になっている行を削除する###
table = table.query("col1_1 != col1_2 and col2_1 != col2_2")
作成処理#
dfの作成###
df = pd.DataFrame(columns=['a'])
df = pd.DataFrame([[1],[2],[3]],columns=['a'])
# df = pd.DataFrame()
# df = pd.DataFrame(data={'a':ac,'count':1},index=range(rows))
# data=を付けないとaがindexになってしまうので注意
# またdata内のインデックスとindex=のインデックスが合わないと値がNaNになってしまう#ので注意
同じ特徴量とサイズを持っている空のDataFrameを生成する###
new_df = df.mask(df.notna())
dfのコピー###
# ポインターコピー (新しい変更は元のdfにも適用される。ただし値の変更のみ。新しい行の追加などは反映さ# れない)
copy_df = df
# 値だけコピー (新しい変更は元のdfに適用されない)
new = old.copy()
# 特定の列だけ値コピー
# 書き方1
new = old[['a', 'c', 'd']].copy()
# 書き方2
new = old.drop('b', axis=1)
列を指定した空のDataFrameの作成###
df = pd.DataFrame(columns=['col1','col2'])
# もし他のデータフレームの列をコピーしたい場合
new_df = pd.DataFrame(columns=df.columns.values)
Numpy Array作成###
データサイズが分かっていない場合
array = np.empty(shape=(0))
array = np.append(array, 2)
print(array) #array = [2]
データサイズが分かっている場合
array = np.zeros(shape=(3))
array[0] = 2
print(array) #array = [2,0,0]
DataFrameの追加###
df1 = pd.DataFrame(columns=['a','b','c'])
# scalarで入れるとindexを指定しないといけないので、リストで入れる。
df1 = df1.append(pd.DataFrame({'a':[1],'b':[2],'c':[3]}),ignore_index=True)
# それかindexを指定する。ignore_indexがあるので一つずつ入れるとインデックスも一つずつ増え #ていく
df1 = df1.append(pd.DataFrame({'a':1,'b':2,'c':3},index=[0]),ignore_index=True)
# a b c
# 0 1 2 3
df = df.append(df1)
サイズが不均等なNumpy arrayの塊を一つずつ同じDataFrameに入れる###
# Data Frameの初期化
df = pd.DataFrame()
# サイズがそれぞれ合わない不均等なデータ
array = np.array([[1,9],[3,4,5],[3]])
for i in range(len(array)):
#要素に対してData Frameを作り、既存のData Frameに加える
new_df = pd.DataFrame({'a':array[i]})
df = df.append(new_df)
print(df)
結果
a
0 1
1 9
0 3
1 4
2 5
0 3
DataFrame → Numpy array###
array = df.values
# dfのcolumn内のvalues
col_array = df.columns.values
0で埋めた新しい列を追加する###
df['new'] = np.zeros(shape=(df.shape[0]))
結果
a b c new
0 0 1 2 0.0
1 3 4 5 0.0
2 5 5 5 0.0
3 4 5 4 0.0
4 52 1 1 0.0
変更処理#
インデックスでフィルター###
x = pd.DataFrame([1,1,1])
x = x.iloc[[1,2]]
二つのデータフレーム内で共通している行だけを取り出す###
# AコラムとBコラムで共通しているdf1内の行を取り出す。
df1 = df1[(df1['A'].isin(df2['A'])) & (df1['B'].isin(df2['B']))]
DataFrameに任意の行を追加する###
df = df.append({'col1':1,'col2':2}, ignore_index=True)
2つのコラムに渡って重複している行を取り出す#
train_df = train_df[train_df.duplicated(subset=['co1','col2'],keep=False)]
# 単に重複している行を取り出したい場合
print(df[df.duplicated(keep=False)])
dtypeを利用したif分###
for col in df.select_dtypes(['float32']).columns.values:
# df[col] = something
df = df.select_dtypes(include=["float64"])
列の値から数字だけを取り出して新たな列を作る###
df['col2_num'] = df['col2'].str.extract('(\d)')
date time オブジェクトに変更する
df[:, "date"] = pd.to_datetime(df.loc[:, "str_date"])
dfから抽出した一つの列を(seriesではなく)dfに保つ方法###
# train_y = train['target']だとtrain_yはseriesになってしまう
# []で囲むことでdataframeに保つことが出来る。
train_y = train[['target']]
条件付きDataFrame加工###
Column cが10以上ならTargetを1、それ以下なら0にして追加する。
条件が一つの場合####
df = pd.DataFrame(np.array([[1,2,3],[4,5,50]]), columns=['a','b','c'])
df['target'] = np.where(df['c'] > 10.0, 1, 0)
結果
# Before
a b c
0 1 2 3
1 4 5 50
# After
a b c target
0 1 2 3 0
1 4 5 50 1
条件が複数ある場合####
df = pd.DataFrame(np.array([[1,2,3],[4,5,50]]), columns=['a','b','c'])
# 条件を設定
conditions = [(df['c'] > 10.0) & (df['b'] > 1.0),
(df['c'] < 10.0) & (df['b'] > 1.0)]
# それぞれの条件に対応する値を設定
choices = [1, 0]
df['target'] = np.select(conditions, choices, default=0)
結果
a b c target
0 1 2 3 0
1 4 5 50 1
条件付きDataFrame加工2###
# col1が1のところを3に変える
# ダメな例
# df[df['col1'] == 1]['col1'] = 3
# 正しい例
df1.loc[df1[df1['col1'] == 1].index,'col1'] = 3
# test_df内のcol1の値のみをtrain_dfから抽出する。
train_df = train_df[train_df['col1'].isin(test_df['col1'].unique())]
locとiloc###
df = pd.DataFrame([[1,2,3],[4,5,6]], columns=['a','b', 'c'])
print(df.loc[:, 'a'])
# print(df.iloc[:, 0])
結果
0 1
1 4
Name: a, dtype: int64
Dataframeのcolumnの長さとrowの長さ###
print(len(train_df))
print(len(train_df.columns))
足りない桁数を0で埋める###
seven = 7
seven = f'{seven:02}' #0が2個で02
# seven = f'{7:02}'
print(seven) #07
特定のインデックスに行を挿入する###
df = pd.DataFrame(np.array([[1,2,3],[4,5,6],[7,8,9]]), columns=['a','b','c'])
# index2に入れたい
line = pd.DataFrame({'a': 3, 'b': 3, 'c':3}, index=[2])
df2 = pd.concat([df.iloc[:2], line, df.iloc[2:]], ignore_index=True)
結果
Before:
a b c
0 1 2 3
1 4 5 6
2 7 8 9
After:
a b c
0 1 2 3
1 4 5 6
2 3 3 3
3 7 8 9
行をシフトする###
簡単。
例:column 'a'を一つシフトする。
df = pd.DataFrame(np.array([[1,2,3],[4,5,6],[7,8,9]]),columns=['a','b','c'])
df['a'] = df['a'].shift(1) #上にシフトしたい場合は-1
結果
a b c
0 NaN 2 3
1 1.0 5 6
2 4.0 8 9
位置で列を選ぶ###
ラベル無しのときとか。
df.iloc[:, 2]
# df[df.columns[2]]
本物のデータから実験用データを作る###
# 一番最初の行から100行分だけ取り出す。
df = df[:100]
DataFrameのindexをリセット###
dropを忘れずに。
df.reset_index(drop=True, inplace=True)
dfの反転###
一行目で反転し、二行目でindexをリセット。
df = df[::-1]
df.reset_index(drop=True, inplace=True)
Column内の特定の数字を置き換えたいとき###
df.replace({'column_1': {-3:0, 3:2}},inplace=True)
重複している列を取り除いて一つの列にする###
df1 = pd.DataFrame(np.array([[1,2,3]]),columns=['a','b','c'])
df2 = pd.DataFrame(np.array([[4,2,3]]),columns=['d','b','c'])
df1 = df1.merge(df2)
# Or
df = pd.concat([df1,df2],axis=1)
df = df.loc[:,~df.columns.duplicated()]
a b c
0 1 2 3
a b c
0 4 2 3
# 結果
a b c d
0 1 2 3 4
条件付きColumnの書き換え###
df.loc[df.col2 == 0, 'col1'] = 'Selling land'
# コラム'game'内の一つ一つの値にKという文字が含まれているか確かめ、その場合は'K'
# を'Good'に置き換える
df.loc[df.setsudo_hi.str.contains('K'), 'game'] = 'Good'
# 複数の場合
searchfor = ['sm','SM']
df.loc[df['device_name'].str.contains('|'.join(searchfor), na=False), 'device_name'] = 'Samsung'
# or文
df.loc[(df.col1 != 'Valuable') & (df.col2 != 'Okay') , 'col3'] = 'Nothing'
# listの中に入っている文字と一致したら
df.loc[df.col1.isin(lst), 'co1'] = 'Valuable'
同じIDでマージする###
x = np.array([[1,9],[2,5],[3,1]])
y = np.array([[1,6],[1,2],[2,3],[3,9],[3,10],[3,11]])
x = pd.DataFrame(x,columns=['id','d'])
y = pd.DataFrame(y,columns=['id','c'])
df = pd.merge(x, y, how='left', on='id')
print(x,'\n')
print(y,'\n')
print(df)
id d
0 1 9
1 2 5
2 3 1
id c
0 1 6
1 1 2
2 2 3
3 3 9
4 3 10
5 3 11
id d c
0 1 9 6
1 1 9 2
2 2 5 3
3 3 1 9
4 3 1 10
5 3 1 11
列をフィルターにかけ、必要な列だけを取り出す###
コラムがC_1,C_2,C_3,A_1,A_2,A_3などとあるときに、Cのつく特徴量だけをサクっと取り出したいときに使える。
A_feats = [i for i in train_df.colums.values if 'A' in i]
変数のイテレーション###
a_1 = [1,2]
a_2 = [3,4]
temp = [5, 6]
for i in range(1,3):
print(eval('a_'+str(i)))
# Assinmentを行いたい場合 Ex: a_i = temp
exec('a_' + str(i) + '= temp')
特定の列内にNaNが入っていない行を取り出す###
df = df[df['col1'].notnull()]
データフレームをシャッフル###
df = df.sample(frac=1).reset_index(drop=True)
df内の列を一つのseriesにまとめる###
df = pd.DataFrame([[1,2,3],[4,5,6]],columns=['a','b','c'])
# a b c
# 0 1 2 3
# 1 4 5 6
s = pd.Series()
for i in df.columns.values:
s = s.append(df[i],ignore_index=True)
# 0 1
# 1 4
# 2 2
# 3 5
# 4 3
# 5 6
# dtype: int64
DataFrameのソート###
df.sort_values(by='col1',ascending=False,inplace=True)
# もし一つの列だけをソートし、他の列に影響を与えたくない場合はnp.sortを利用
x = np.sort(df['col1'].values)[::-1]
df['col1'] = pd.Series(x)
2つのDataFrameを連結する###
ただしconcatはメモリの消費が激しいので大きなデータセットのときは要注意。
# Rowを連結したい場合。例えばdf1=[col1,col2](10 rows),
# df2=[col1,col2] (20 rows)を連結してdf=[col1,col2] (30 rows)とするとき。
df = pd.concat([df1,df2], ignore_index=True)
# Columnを連結したい場合。例えばdf1=[col1,col2](10 rows),
# df2=[col3] (10 rows)を連結してdf=[col1,col2,col3] (10 rows)とするとき。
df = pd.concat([df1,df2], axis=1)
EDA#
DataFrame内の文字を分割して値を挿入する###
x = np.array([['a.b','c.d'],['e.f','gh']])
df = pd.DataFrame(x,columns=['A','B'])
# df:
# A B
# 0 a.b c.d
# 1 e.f gh
new = df['B'].str.split('.')
# new:
# 0 [c, d]
# 1 [gh]
# /で分けて特徴量を作る。
df[['year','month','date']] = df['date'].str.split('/', expand=True)
# 分割後、0番目のリストの値を挿入
df['first'] = df['construct_name'].str.split('_').str[0]
# df['B']:
# 0 c
# 1 gh
# 整数で分割後、0番目のリストの値の最後のを挿入
train['Cabin_Char'] = train['Cabin'].str.split('\d').str[0].str[-1]
ある列Xがnanのところだけある列Yの値で埋める###
lst = df[df['x'].isna()].index
for i in lst:
df.loc[i,'x'] = df['y'].iloc[i]
groupby###
df = train_df.groupby('col1',as_index=False).mean()
df = pd.DataFrame(data={'col1':df['col1'],'col2':df['col2']}, \
index=range(df.shape[0]))
Unique Valuesを調べる###
# Unique valuesの数
print('Number of unique values in col1',df['col1'].nunique())
# Unique values
print('Unique values in col1',df['col1'].unique())
# df2のcol1にあってdf1のcol1に無い値を調べる
print(df2[~df2['col1'].isin(df1['col1'])]['col1'].unique())
2つのarray内を比べた時に、いずれかに無い値を出力する###
2つのデータフレームのコラムの違い等を確かめたいときに使える。またnumpy arrayとpython arrayどちらでも使える。
# array1にあってarray2にない要素を返す。
np.setdiff1d(array1, array2)
# array2にあってarray1にない要素を返す。
np.setdiff1d(array2, array1)
ある値を他のデータフレームを参照しながら更新###
train_df['temp'] = train_df['col1']
for val,new_val inzip(df['col1'].values,df['new_col1'].values):
train_df.loc[train_df['col1'] == val, 'temp'] = new_val
train_df['jukyo'] = train_df['temp']
train_df.drop('temp',axis=1,inplace=True)
一つの列に全ての列の値をまとめる###
# 列が膨大な場合
df = pd.melt(df, id_vars=[], value_vars=df.columns.values)
df.dropna(inplace=True)
df.drop('variable',axis=1,inplace=True)
df.rename(columns={'variable':'col1'},inplace=True)
# https://pandas.pydata.org/pandas-docs/stable/reference/api/pandas.DataFrame.stack.html
# .stack()でも良し
# 少ないなら
df = pd.DataFrame({'col1':['A', 'B', 'C', 'D'],'col2':['E', 'F', 'G', 'H']})
df = df['col1'].append(df['col2']).reset_index(drop=True)
データフレーム間の細かい値の移動###
train_df = pd.DataFrame({'col1':['A', 'B', 'C', 'D','E'],'col2':['E', 'F', 'G', 'H',np.nan]})
test_df = pd.DataFrame({'col1':['I', 'J', 'K', 'L','M'],'col2':['N', 'O', 'P', 'Q',np.nan]})
# train_df:
col1 col2
0 A E
1 B F
2 C G
3 D H
4 E NaN
train_df.loc[[0,1],'col1'] = test_df.loc[[0,1],'col1']
# train_df:
col1 col2
0 I E
1 J F
2 C G
3 D H
4 E NaN
値の重複カウント###
df = pd.DataFrame(np.array([[1,1,1],[1,2,3],[1,4,5]]), columns=['a','b','c'])
df = df.apply(lambda x: x.duplicated()).sum()
結果
a b c
0 1 1 1
1 1 2 3
2 1 4 5
a 2
b 0
c 0
dtype: int64
a-column内の1自体のカウントは+1して3ということに注意。.duplicated()が[False, True, True]のため。
とある列でgroupbyして、他の列のunique valuesを数える###
df = pd.DataFrame([[124,200,1],[124,2000,2],[3000,3000,3],[125,3000,4],[125,3000,5],[123,200,6]],columns=['col1','col2','col3'])
# col1で行をまとめて、col2のユニークな値の数を数える
print(df.groupby('co11')['col2'].nunique())
# col1
# 123 1
# 124 2
# 125 1
# 3000 1
Columnの詳細な情報を知りたいとき###
print(df['groups'].describe())
count 4137.000000
mean 9.385303
std 5.458562
min 0.000000
25% 4.000000
50% 9.000000
75% 13.000000
max 19.000000
Name: groups, dtype: float64
column内の全ての値とその数をカウント###
print(df['col1'].value_counts())
# col1の値をソートして表示したい場合
print(df['col1'].value_counts().sort_index())
Nullになっている行のインデックスが知りたい###
print(np.where(df['col1'].isnull())[0])
# 例:[1,4]
特徴量の名前と数が知りたいとき###
print(df.columns.values)
print(len(df.columns))
2つのデータフレームの違いを知る###
df = pd.concat([df1,df2]).drop_duplicates(keep=False)
level0のインデックスの観点から一つの列の値の重複を確認する###
インデックスが複数で層になっているときに、一番最初の層の観点から重複を探すにはどうすれば良いか。
df = df[df['col1'].groupby(level=0).apply(lambda x: x.duplicated())]
相関性ランキング###
それぞれの特徴量の相関性を強い順にランキング化する。
df = pd.DataFrame(np.array([[5,2,3],[1,3,2],[5,8,5]]), columns=['a','b','c'])
correlations = df.corr().abs().unstack().sort_values(kind="quicksort", ascending=False).reset_index()
correlations = correlations[correlations['level_0'] != correlations['level_1']]
print(correlations.head(10))
# targetとの相関
result = df.drop("target", axis=1).apply(lambda x:x.corr(df['target'])).sort_values(ascending=False)
結果
level_0 level_1 0
3 c b 0.882498
4 b c 0.882498
5 c a 0.755929
6 a c 0.755929
7 b a 0.359211
8 a b 0.359211
2つの列の相関性###
df['A'].corr(df['B'])
出力処理
特徴量からカテゴリー変数名と数値変数名を一発で取得###
# df内のカテゴリ変数名を取得
categories = df.select_dtypes(include='object').columns.values
# df内の数値変数名を取得
numerics = ['int16', 'int32', 'int64', 'float16', 'float32', 'float64']
numerics = df.select_dtypes(include=numerics).columns.values
# 念のため他の型の変数が無いかをチェック
others = [col for col in df.columns.values if col not in np.concatenate((categories, numerics), axis=0)]
print(others)
データフレームの列間隔のズレを直して綺麗に出力したいとき###
値に日本語が入ったりしているとデータフレーム内の列の間隔がズレることがある。これはEDAのときなどにされるとデータフレームの値が見にくい。このtabulateというパッケージを使えばデータフレームがテーブル形式でプリントされ、大変見やすくなる。
from tabulate import tabulate
import pandas as pd
print(tabulate(df, headers='keys', tablefmt='psql'))
numpy array or DataFrameを省略せずに全て出力する###
# Numpy array
import sys
np.set_printoptions(threshold=sys.maxsize)
# DataFrame
# 縦と横幅
pd.set_option("display.max_rows", None, "display.max_columns", None)
with pd.option_context('display.max_rows', None, 'display.max_columns', None):
print(df)
# 横幅の設定 (columnに入っている値が長すぎると途切れてしまうので)
pd.set_option('max_colwidth', 200)
指数表記(Scientific notation)をオフにする###
np.set_printoptions(suppress=True)
特徴量生成とエンコーディング
他の特徴量をグループ化して統計量を取る###
# pclassをグループとして各々グループから年齢の中央値を取りmid_age_per_classとする。
train_test['age_per_class'] = train_test.groupby('Pclass')['Age'].transform('median')
ラベルエンコーダー (Label Encoder)###
label_encoder = LabelEncoder()
df.loc[:,'col1'] = label_encoder.fit_transform(df.loc[:,'col1'])
相関(Correlation)が強い特徴量を落として無駄削減###
どちらかというとFeature Selection。
X = np.array([[1, 1, 1],
[2, 2, 0],
[3, 3, 1],
[4, 4, 0],
[5, 5, 1],
[6, 6, 0],
[7, 7, 1],
[8, 7, 0],
[9, 7, 1]])
df = pd.DataFrame(X)
# Create correlation matrix
corr_matrix = df.corr().abs()
# Select upper triangle of correlation matrix
upper = corr_matrix.where(np.triu(np.ones(corr_matrix.shape), k=1).astype(np.bool))
# Find index of feature columns with correlation greater than 0.95
to_drop = [column for column in upper.columns if any(upper[column] > 0.95)]
# Drop features
df.drop(to_drop, axis=1, inplace=True)
結果
0 2
0 1 1
1 2 0
2 3 1
3 4 0
4 5 1
5 6 0
6 7 1
7 8 0
8 9 1
ここから
https://chrisalbon.com/machine_learning/feature_selection/drop_highly_correlated_features/
numpy arrayとlist#
特定の条件を満たす数字をnumpy arrayから抽出する###
x = np.array([0,1,2,3,4])
x = x[(x>0) & (x<4)] #結果:[1 2 3]
一行 list for文まとめ###
list = [i for i in ratio.columns.values if ("expected_" in i) and not("unexpected_" in i)]
lst = [i for i in range(10)]
# if
test_fold = [0 for i in range(x_train.shape[0]) if ...]
# if and else
test_fold = [0 if ... else 1 for i in range(x_train.shape[0])]
Numpy arrayの行の反転###
array = np.flip(array)
特定の条件を満たす数字を2次元のnumpy arrayから抽出する###
x[1]で数字5以下の満たすx[1]と、それに対応するx[0]を取り出すという仮定で書いています。
x = np.array([[0,1,2,3],[3,4,5,6]])
boolArr = x[1] < 5
y = np.zeros(shape=(2,2))
y[0], y[1] = np.extract(boolArr, x[0]), np.extract(boolArr,x[1])
# 結果[[0. 1.]
# [3. 4.]]
2D listに値を挿入###
x = np.array([[1,2,3,4,5,1,2],[5,1,2,3,2,2,3]])
low = list([[],[]])
low[0].append(x[0][0])
low[1].append(x[1][0])
print(low)
# 結果 low = [[1], [5]]
Numpy arrayのソート###
x_1 = np.array([0,18,90,7,8,9])
x_1 = np.sort(x_1)
# 結果 [ 0 7 8 9 18 90]
x_1 = np.sort(x_1)[::-1]
# 結果 [90 18 9 8 7 0]
条件付きNumpy Array加工###
例題:要素が5以下ならそのままにし、要素が5以上なら10掛ける。
array = np.arange(10)
# array=[0, 1, 2, 3, 4, 5, 6, 7, 8, 9]
array = np.where(array < 5, array, 10*array)
# 構文 array = np.where(条件, Trueの場合, Falseの場合)
# array([ 0, 1, 2, 3, 4, 50, 60, 70, 80, 90])
list → Numpy array###
array = np.array(list)
Numpy array→list###
lst = numpy_array.tolist()
listのextend###
aList = [123, 'xyz', 'zara', 'abc', 123];
bList = [2009, 'manni'];
aList.extend(bList)
# aList: [123, 'xyz', 'zara', 'abc', 123, 2009, 'manni']
要素を削除する###
# list
del t[0]
# or
t.pop()
# numpy array
# np.delete(x,index,axis)
x = np.delete(x, 1, 0)
# 特定のインデックスを削除したい場合
x = np.delete(x, [1,2,5], 0)
# 特定のインデックス以上を削除したい場合
x = np.delete(x, np.s_[3:], axis=1)
ファイルの読み書き
csvファイルの読み込みと書き込み###
df = pd.read_csv('.csv')
df.to_csv('.csv',index=False)
# 日本語の文字化け対策
df.to_csv('.csv',encoding='shift_jis',index=False)
feather file書き込みと読み込み###
pip install feather-formatでインストール
import feather
# 単にcsvファイルをfeatherファイルに変換したい場合
df = pd.read_csv('./df.csv')
feather.write_dataframe(df, './df.feather')
# 特徴量をそれぞれfeatherファイルに保存したい場合
df = pd.DataFrame(np.array([1]),columns=['a'])
feather.write_dataframe(df, './dataset/test')
# df.to_feather('')でも可。feather fileはfloat16をサポートしていないので注意
df = feather.read_dataframe('./dataset/test')
# df内の列を一つずつfeather形式で保存
# index=をちゃんと設定しないとエラーが起こる。またObject dtypeも他のdtypeに直す# 必要あり。
for col in train_df.columns.values:
pd.DataFrame(data={str(col):train_df[col]},index=range(train_df.shape[0])).to_feather(str(col) + '_train.ftr')
pd.DataFrame(data={str(col):test_df[col]},index=range(test_df.shape[0])).to_feather(str(col) + '_test.ftr')
pickleファイルを開く###
import pickle
with open('df1.pkl', 'rb') as df1, open('df2.pkl', 'rb') as df2:
df1, df2 = pickle.load(df1), pickle.load(df2)
その他
Suppress warnings
import warnings
warnings.filterwarnings("ignore")
データの型変換まとめ###
List
list = [int(string) for string in lst]
Numpy array
numpy_array = numpy_array.astype(int)
Series
series = series.astype(int)
DataFrame
df = df.astype(int)
Python array
array = array.astype(int)
普通のstring
s = int(s)
カレントディレクトリの設定###
データ整形と関係ないけど。。
import os
# print(os.getcwd())
os.chdir("C:\\Users\\dravr\\Documents\\kaggle\\IEEE\\dataset")
index.map() 複数の入力値から呼応した一つの出力値を特徴量に加える###
series.map()やindex.map()を使えば、与えられた入力値から簡単に出力値を得ることが出来る。以下は、その入力値が複数の場合に有用である。
# 複数の特徴量のグループから生存率を出す。(出力値:家族生存率)
reference = df.groupby(['Last_name','SibSp','Embarked','Pclass'])['Survived'].mean()
# .index.map()を使うためにmapの複数の入力値をインデックスに加える
train = train.set_index(['Last_name','SibSp','Embarked','Pclass'],drop=True)
test = test.set_index(['Last_name','SibSp','Embarked','Pclass'],drop=True)
# 複数の入力値に呼応した一つの出力値、家族生存率を特徴量に加える。
# (series.map()の場合、dataframe.map()として使えない(入力値は一つだけ)のでindex.mapを使っている。)
train['Family_sur_rate'] = train.index.map(reference)
test['Family_sur_rate'] = test.index.map(reference)
# 入力値として使ったインデックスを特徴量に戻す
train = train.reset_index(level=['Last_name','SibSp','Embarked','Pclass'])
test = test.reset_index(level=['Last_name','SibSp','Embarked','Pclass'])
特徴量エンジニアリング
ラグ
for shift in [0, 1, 2]:
data[f"shift_t{shift}"] = data.groupby(["id"])["demand"].transform(
lambda x: x.shift(shift)
)
ローリング(窓)
for size in [7, 14,21, 30, 60, 90, 180]:
data[f"rolling_std_t{size}"] = data.groupby(["id"])["demand"].transform(
lambda x: x.shift(1).rolling(size).mean()
)
# .skew() .kurt() .std() .max() .min()
エンコーディング
カウントエンコーディング
count_features = ['Age','SibSp','Cabin','Ticket']
for feature in count_features:
train['count_' + feature] = train[feature].map(pd.concat([train[feature],
test[feature]], ignore_index=True).value_counts(dropna=False))
test['count_' + feature] = test[feature].map(pd.concat([train[feature],
test[feature]], ignore_index=True).value_counts(dropna=False))
ターゲットエンコーディング (スムーズ)
import numpy as np
import pandas as pd
def add_noise(series, noise_level):
return series * (1 + noise_level * np.random.randn(len(series)))
def target_encode(trn_series=None,
tst_series=None,
target=None,
min_samples_leaf=1,
smoothing=1,
noise_level=0):
"""
Smoothing is computed like in the following paper by Daniele Micci-Barreca
https://kaggle2.blob.core.windows.net/forum-message-attachments/225952/7441/high%20cardinality%20categoricals.pdf
trn_series : training categorical feature as a pd.Series
tst_series : test categorical feature as a pd.Series
target : target data as a pd.Series
min_samples_leaf (int) : minimum samples to take category average into account
smoothing (int) : smoothing effect to balance categorical average vs prior
"""
assert len(trn_series) == len(target)
assert trn_series.name == tst_series.name
temp = pd.concat([trn_series, target], axis=1)
# Compute target mean
averages = temp.groupby(by=trn_series.name)[target.name].agg(["mean", "count"])
# Compute smoothing
smoothing = 1 / (1 + np.exp(-(averages["count"] - min_samples_leaf) / smoothing))
# Apply average function to all target data
prior = target.mean()
# The bigger the count the less full_avg is taken into account
averages[target.name] = prior * (1 - smoothing) + averages["mean"] * smoothing
averages.drop(["mean", "count"], axis=1, inplace=True)
# Apply averages to trn and tst series
ft_trn_series = pd.merge(
trn_series.to_frame(trn_series.name),
averages.reset_index().rename(columns={'index': target.name, target.name: 'average'}),
on=trn_series.name,
how='left')['average'].rename(trn_series.name + '_mean').fillna(prior)
# pd.merge does not keep the index so restore it
ft_trn_series.index = trn_series.index
ft_tst_series = pd.merge(
tst_series.to_frame(tst_series.name),
averages.reset_index().rename(columns={'index': target.name, target.name: 'average'}),
on=tst_series.name,
how='left')['average'].rename(trn_series.name + '_mean').fillna(prior)
# pd.merge does not keep the index so restore it
ft_tst_series.index = tst_series.index
return add_noise(ft_trn_series, noise_level), add_noise(ft_tst_series, noise_level)
train_df = pd.DataFrame(np.array([[3,2,1],[6,2,1],[7,1,0]]),columns=['feature1','category1','target'])
test_df = pd.DataFrame(np.array([[3,2,1],[6,2,1],[7,1,0]]),columns=['feature1','category1','target'])
train_df['target_encoded'], test_df['target_encoded'] = target_encode(train_df["category1"],
test_df["category1"],
target=train_df.target,
min_samples_leaf=1,
smoothing=1,
noise_level=0.01)
print(train_df)