import numpy as np
import pandas as pd
import matplotlib.pyplot as plt
# グラフをinline表示可能にする
%matplotlib inline
# 解像度を上げてinline表示する
%config InlineBackend.figure_format = 'retina'
# 日本語表示用ライブラリ(matplotlibで日本語を使用したい場合)
import japanize_matplotlib
# excelファイルの直接読み込み(シート名指定)
url = 'https://www.ces-alpha.org/course/file_serve/5650149854412800/class_score.xlsx'
df1 = pd.read_excel(url, sheet_name = 'score')
df1.head()
# データサイズの確認
len(df1)
# データサイズの確認
df1.shape
df1.info()
# 基本統計量
df1.describe()
ls d:\Users\Desktop
# 点数のリスト
subjects = [df1['国語'], df1['数学'], df1['理科'], df1['社会'], df1['英語']]
# 外れ値用マーカー設定
flierprops = dict(marker="o", markerfacecolor='orange', markersize=8, markeredgecolor='none')
# 胴体設定
plt.gca().boxplot(subjects,
patch_artist=True,
flierprops = flierprops,
boxprops=dict(facecolor='pink'),
medianprops=dict(color='red', linewidth=1)
)
plt.title('科目別得点分布', fontsize=14)
plt.xlabel('科目', fontsize=12)
plt.ylabel('得点分布', fontsize=12)
plt.xticks([1,2,3,4,5], ('国語', '数学', '理科', '社会', '英語'))
plt.ylim([0,105])
plt.grid(False)
# グラフの保存(各自の環境に応じて保存パスを変えて下さい)
#plt.savefig(r'd:\Users\Desktop\boxplot1.png', bbox_inches='tight', dpi=360, transparent=False);
# 相関係数
corr = df1.corr()
corr # id が邪魔
# 指定列を一時的に削除
df1.drop(['id', '性別'], axis=1).head() # axis=0 は行、axis=1 は列
df1.head() # 復活する 恒久的に消すには、 上で axis=1 の後に ,inplace=True を追記
corr = df1.drop(['id', '性別'], axis=1).corr()
corr
import seaborn as sns
sns.heatmap(corr, vmax=1, vmin=-1, center=0);
plt.figure(figsize=(5, 5))
p = sns.heatmap(corr, annot=True, fmt='.2f', annot_kws={"fontsize":12}, cmap='tab20c_r', linewidths=1, square=True, cbar=False)
#p.set_title("Plot", fontsize = 20)
#p.set_xlabel("X-axis", fontsize = 18)
#p.set_ylabel("Y-axis", fontsize = 18)
p.set_xticklabels(p.get_xmajorticklabels(), fontsize = 16)
p.set_yticklabels(p.get_ymajorticklabels(), fontsize = 16)
# List of colormap
print(dir(plt.cm))
print(df1.describe().index)
print(df1.describe().columns)
# 列の抽出
df1.describe()['国語']
tmp = df1.describe()
tmp['国語']
# 行の抽出
tmp.loc['75%']
# index, column名で指定 (loc)
tmp.loc['75%','英語']
tmp
# 番号で指定 (iloc)
tmp.iloc[1, 3]
# 番号で行指定 (iloc)
tmp.iloc[1,:]
# 番号で列指定 (iloc)
tmp.iloc[:, 3]
# 番号で連続する行指定 (iloc)
tmp.iloc[1:3, :]
# 番号で連続する列指定 (iloc)
tmp.iloc[:, 0:3] # 0 は省略可
# 番号で連続する列指定 (iloc)
tmp.iloc[:, 3:] # 後ろを省略すると最終列まで
# 国語合格者
ja_pass = df1['国語'] >= 60
ja_pass
df1[ja_pass]
ma_pass = df1['数学'] >= 60
en_pass = df1['英語'] >= 60
sc_pass = df1['理科'] >= 60
so_pass = df1['社会'] >= 60
# 全科目合格者
df1[ja_pass & ma_pass & en_pass & sc_pass & so_pass]
# 英数国は合格で、理または社何れかの合格者
df1[ja_pass & ma_pass & en_pass & (sc_pass | so_pass)]
# 数学「秀」
df1[ df1['数学'] >= 90 ]
# 国語「秀」 or 数学「秀」
df1[ (df1['国語'] >= 90) | (df1['英語'] >= 90) ]
# 国語:平均点以上 かつ 数学:中央値以上
df1[ (df1['国語'] >= df1['国語'].mean()) & (df1['数学'] >= df1['数学'].median()) ]
# 英語点数でソート(降順)
df_en = df1.sort_values('英語', ascending = False)
df_en.head()
df_en.columns
# 列の並べ替え(一時的な表示)
df_en.reindex(['英語', '国語', '数学', '理科', '社会'], axis=1).head() # axis=0 は行、axis=1 は列
df_en.head()
# 新しい列を追加
df1['合計'] = 0
df1.head()
# 新しい列を追加
df1['合計'] = df1['国語'] + df1['英語']
df1.head()
# 新しい列を追加
df1.iloc[:, 2:7].head()
# 新しい列を追加
total = df1.iloc[:, 2:7].sum(axis=1)
total
df1['合計'] = total
df1.head()
df1['total'] = df1.iloc[:, 2:7].sum(axis=1)
df1.head()
# 列同士の演算
df1['new'] = df1['国語'] / df1['理科']
df1.head()
# 列の削除
df1.drop(['合計'], axis=1, inplace=True) # inplace=True で上書きする
df1.head()
apply: https://pandas.pydata.org/pandas-docs/stable/reference/api/pandas.DataFrame.apply.html
map: https://pandas.pydata.org/docs/reference/api/pandas.Series.map.html
assign: https://pandas.pydata.org/pandas-docs/stable/reference/api/pandas.DataFrame.assign.html
# 関数の復習
def myfunc(x):
return x ** 2 # 入力 x の2乗を返す
myfunc(10)
# dataframeの列を入力する
df1['国語'] = df1['国語'].apply(myfunc)
df1.head()
# dataframeの列を入力する
df1['理科'] = df1['理科'].map(myfunc)
df1.head()
# dataframe の列を入力する
df1['英語'] = df1['英語'].apply(lambda x: x * 10)
df1.head()
df1.head()
# dataframe を丸ごと入力 + 新列追加を同時に
df1['new2'] = df1.apply(lambda x: (x['数学'] * 2 + x['社会']), axis=1)
df1.head()
# dataframe を丸ごと入力 + 新列追加を同時に
df1.assign(score = lambda x: (x['数学'] * 2 + x['社会'])).head()
# リセットするため再度元ファイルを読み直す
df1 = pd.read_excel(url, sheet_name = 'score')
df1.head()
df1 = df1.assign(total = lambda x: x.iloc[:, 2:7].sum(axis=1))
# 氏名情報ファイルを読み込む
df2 = pd.read_excel(url, sheet_name = 'name')
df2.head()
# 結合の際の key となる列名の変更
# なんちゃって個人情報 (http://kazina.com/dummy/)
df2.rename(columns={'番号': 'id'}, inplace = True)
df2.head()
# 2つの共通の key列名 を持つ dataframeを統合
df12 = pd.merge(df1, df2, on='id', how='left')
df12.head()
# id番号順ソート(降順)
df12 = df12.sort_values('id', ascending = True)
df12.head()
# 列の並べ替え(一時的な表示)
df12 = df12.reindex(['id', '氏名', '性別','英語', '国語', '数学', '理科', '社会', 'total'], axis=1)
df12.head()
df12.query('英語 >= 80')
df12.query('total >= 300')
df12.query('英語 >= 80 & 社会 >= 80')
df12.query('id == 4')
df12.query('氏名 == "西脇 まさし"')
今までもっぱら df['列名'] と書いてきたが、df.列名 とも書ける。
df12['英語']
df1.英語