多変数のロジステック回帰をライブラリ無しでやってみるという記事を書きました。(2/18発売)
コードだけGithubにあります。 https://github.com/tsjshg/sd201903
# pdと略されることが多い
import pandas as pd
# 辞書で渡すと列ごとに
df = pd.DataFrame({'col_0': [1,2,3], 'col_1': [10,20,30]}, index=['row_0', 'row_1', 'row_2'])
df
# リストで渡すと行ごとに
df = pd.DataFrame([[1,10], [2,20], [3,30]], columns=['col_0', 'col_1'], index=['row_0', 'row_1', 'row_2'])
df
# (行数、列数)
df.shape
df.columns
df.columns[0] = 'COL_0'
# 全体を1度に変更するのは可能
df.columns = ['col_0', 'col_1']
# 個別に変えたかったらrename
df.rename(columns={'col_0': 'COL_0'})
# 行の名前
df.index
# numpy.ndarray
df.values
# 普通にやると列 (行がサンプル、列が説明変数)
df['col_0']
# 行を名前で指定
df.loc['row_0']
df.loc['row_0',:]
df.loc[:, 'col_1']
df.loc['row_0', 'col_0']
# 添え字でアクセスしたいときは、iloc
df.iloc[1,0]
df.iloc[1]
df.iloc[1,:]
# 集計のための関数多数
df.sum()
# axis=0は行方向へ計算が進む意味
df.sum(axis=0)
df.sum(axis=1)
df.mean() # 平均
df.median() # 中央値
df.std() # 標準偏差
df.var() # 分散
df
# 新たな列の追加
df['col_2'] = [100, 200, 300]
df
# 計算結果の追加
df['sum'] = df.sum(1)
df
# 列同士の計算もOK
df['col_2/col_0'] = df['col_2'] / df['col_0']
df
# 行や列をまとめて消せます
df.drop(['sum', 'col_2/col_0'], axis=1)
# 破壊的な方が良い場合は、inplace=True
df.drop(['sum', 'col_2/col_0'], axis=1, inplace=True)
df
# 昔はsortだった。
df.sort_values(by='col_2', ascending=False)
# 複数の列を指定することも可能
df.sort_values(by=['col_0', 'col_1'])
# 行の名前でソートしたいとき。
df.sort_index(ascending=False)
# 値の評価
df > 20
df_with_nan = df[df > 20]
df_with_nan
# NaNはNot a Number 「数字じゃない」の意味
import numpy as np
type(np.nan)
np.nan == np.nan
df_with_nan
df_with_nan.iloc[0,0] == df_with_nan.iloc[0,1]
# None は何もないというシングルトン
None == None
if None:
print('なにも無い')
if np.nan:
print('数字ではないものがある')
val = np.nan
if val == np.nan:
print('これではダメ')
if np.isnan(val):
print('NaNだとわかる')
df_with_nan
df_with_nan.isna()
df_with_nan.dropna()
df_with_nan.dropna(how='all', axis=1)
df_with_nan.fillna(0)
# 破壊的
df_with_nan[df_with_nan.isna()] = 0
df_with_nan
# 2行目だけをとってくる
idx = [False, True, False]
df[idx]
df['col_0'] <= 2
# 3で割り切れる
df['col_0'] % 3 == 0
df[df['col_0'] % 3 == 0]
# SQL文のように書ける
df.query('col_0 >=2 and col_2 > 200')
# 行や列ごとに計算したいとき。for文は使わない
def what(x):
return type(x)
df.apply(what)
df.apply(what, axis=1)
df
# 無名関数が便利
df.apply(lambda x: x.sum(), axis=1)
# Series全体への計算
df.apply(lambda x: x * 2)
# 普通はこうする
df * 2
# 個別の要素へ関数を適用
import random
df.applymap(lambda x: random.randint(1,x))
# Series型には、mapがある
df['col_0'].map(lambda x: f'val = {x}')
メソッドの名前と引数
apply使うより、mapの方が速いらしい
https://shinyorke.hatenablog.com/entry/pandas-tips#map%E3%81%A7%E6%9B%B8%E3%81%8D%E7%9B%B4%E3%81%99
# CSVへ保存
df.to_csv('sample.csv')
!cat sample.csv
pd.read_csv('sample.csv', index_col=0)
df.to_excel('sample.xlsx')
pd.read_excel('sample.xlsx')
df.to_pickle('sample.pkl')
pd.read_pickle('sample.pkl')
# サンプルデータのロード
from sklearn.datasets import load_iris
iris = load_iris()
iris_df = pd.DataFrame(iris.data, columns=iris.feature_names)
iris_df['target'] = iris.target
iris_df.shape
# データの先頭部分 sepal(萼)、petal(花弁)
iris_df.head()
iris_df.tail()
iris_df.describe()
iris_df.info()
%matplotlib inline
iris_df['sepal length (cm)'].plot(kind='hist')
iris_df.iloc[:,:4].plot(kind='hist', alpha=0.8)
iris_df.iloc[:,:4].plot(kind='box')
from pandas.plotting import scatter_matrix
_ = scatter_matrix(iris_df.iloc[:, :4])
iris_df.sample(10)
gr = iris_df.groupby('target')
gr.get_group(0)
gr.apply(lambda x: x['sepal length (cm)'].mean())