Last active
December 26, 2023 07:56
-
-
Save okotani/5308b139af24457ed1cf08c4f6872180 to your computer and use it in GitHub Desktop.
初学者向けPolars100本ノック
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
# 参照元:初学者向けPolars100本ノック | |
# (https://github.com/kunishou/Polars_100_knocks/blob/main/01_Polars_100_Knocks_for_colab.ipynb) | |
# Python:3.12.1 (main, Dec 7 2023, 20:45:44) [Clang 15.0.0 (clang-1500.0.40.1)] | |
# polars:0.20.2 | |
# %% | |
# 【1】 | |
df = initialize1() # 初期化 | |
for col in df.get_columns(): | |
display("column:" + col.name, col.value_counts()) | |
# %% | |
# 【37】 | |
df2 = initialize2() # 初期化 | |
df2 = df2.join(df3, how="anti", on="name") | |
df2 | |
# %% | |
# 【71】 | |
# df2とdf3のそれぞれの行を全通り組み合わせた | |
# dataframeを作成 | |
print(ans[71]) # 解答表示 | |
df2 = initialize2() # 初期化 | |
df2 = df2.join(df3, how="cross", on="name") | |
df2 | |
# %% | |
# 【72】 | |
# df2とdf4を列方向に連結し、df2に格納 | |
print(ans[72]) # 解答表示 | |
df2 = initialize2() # 初期化 | |
# 同じ名前の列があるとhow='horizontal'できないのでそれは消しておく必要がある。 | |
df2 = pl.concat([df2, df4.drop("name")], how="horizontal") | |
df2 | |
# %% | |
# 【73】 | |
# df2とdf4を行方向に連結し、df2に格納 | |
print(ans[73]) # 解答表示 | |
df2 = initialize2() # 初期化 | |
# 列が一致しない同士を立結合するにはhow="diagonal"が必要 | |
df2 = pl.concat([df2, df4], how="diagonal") | |
df2 | |
# %% | |
# 【74】 | |
# dfのage列の平均値を確認 | |
print(ans[74]) # 解答表示 | |
df = initialize1() # 初期化 | |
df.select("age").mean() | |
# %% | |
# 【75】 | |
# dfのage列の中央値を確認 | |
print(ans[75]) # 解答表示 | |
df = initialize1() # 初期化 | |
df.select("age").median() | |
# %% | |
# 【76】 | |
# ①df2の生徒ごとの合計点(行方向の合計) | |
# ②df2の科目ごとの点数の総和(列方向の合計) | |
print(ans[76]) # 解答表示 | |
df2 = initialize2() # 初期化 | |
display( | |
df2.with_columns( | |
# pl.sum()の横方向計算は非推奨。sum_horizontal()が推奨。 | |
pl.sum_horizontal(pl.exclude("name", "class")) | |
) | |
) | |
df2.sum() | |
# %% | |
# 【77】 | |
# df2のEnglishで得点の最大値 | |
print(ans[77]) # 解答表示 | |
df2 = initialize2() # 初期化 | |
df2.select("English").max() | |
# %% | |
# 【78】 | |
# df2のEnglishで得点の最小値 | |
print(ans[78]) # 解答表示 | |
df2 = initialize2() # 初期化 | |
df2.select("English").min() | |
# %% | |
# 【79】 | |
# df2においてclassでグルーピングし、クラスごとの科目の | |
# 最大値、最小値、平均値を求める(name列は削除しておく) | |
print(ans[79]) # 解答表示 | |
df2 = initialize2() # 初期化 | |
display(df2.drop("name").group_by("class").min()) | |
display(df2.drop("name").group_by("class").max()) | |
display(df2.drop("name").group_by("class").mean()) | |
# %% | |
# 【80】 | |
# df2においてclassでグルーピングし、aggを用いて | |
# 各科目の平均、最大値、最小値を求める | |
# なお、各科目の平均、最大値、最小値には | |
# 「***_mean」のようにsuffixを振ること | |
print(ans[80]) # 解答表示 | |
df2 = initialize2() # 初期化 | |
df2.drop("name").group_by("class").agg( | |
pl.all().min().suffix("_min"), | |
pl.all().max().suffix("_max"), | |
pl.all().mean().suffix("_mean"), | |
) | |
# %% | |
# 【81】 | |
# dfの各列間の(Pearson)相関係数を確認 | |
print(ans[81]) # 解答表示 | |
df = initialize1() # 初期化 | |
# 上の解答のpearson_corr()は古い名前で今はcorr() | |
# corr()は文字列型はエラーになるので除いておく | |
df.select(pl.exclude(pl.Utf8)).corr() | |
# %% | |
# 【82】 | |
# scikit-learnを用いてdf2のEnglish、Mathematics、History列を標準化する | |
# (from sklearn.preprocessing import StandardScalerをインポート) | |
print(ans[82]) # 解答表示 | |
df2 = initialize2() # 初期化 | |
from sklearn.preprocessing import StandardScaler | |
df2 = df2.drop("name", "class") # 計算しない列は除いておく | |
scaler = StandardScaler() | |
# 上の解答のDataFrame()の"columns="は今は無い。代わりにschema=を使う。 | |
df2_std = pl.DataFrame(scaler.fit_transform(df2.to_numpy()), schema=df2.columns) | |
display(df2_std) | |
display(df2_std.describe()) # 各科目のstdが同じ値になるはず。 | |
# %% | |
# 【83】 | |
# scikit-learnを用いてdf2のEnglish列を標準化する | |
# (from sklearn.preprocessing import StandardScalerをインポート) | |
print(ans[83]) # 解答表示 | |
df2 = initialize2() # 初期化 | |
from sklearn.preprocessing import StandardScaler | |
df2 = df2.select("English") # 計算しない列は除いておく | |
scaler = StandardScaler() | |
# 上の解答のDataFrame()の"columns="は今は無い。代わりにschema=を使う。 | |
df2_std = pl.DataFrame(scaler.fit_transform(df2.to_numpy()), schema=df2.columns) | |
display(df2_std) | |
display(df2_std.describe()) # 各科目のstdが同じ値になるはず。 | |
# %% | |
# 【84】 | |
# scikit-learnを用いてdf2のEnglish、Mathematics、History列を | |
# Min-Maxスケーリングする | |
# (from sklearn.preprocessing import MinMaxScalerをインポート) | |
print(ans[84]) # 解答表示 | |
df2 = initialize2() # 初期化 | |
from sklearn.preprocessing import MinMaxScaler | |
df2 = df2.drop("name", "class") # 計算しない列は除いておく | |
scaler = MinMaxScaler() | |
# 上の解答のDataFrame()の"columns="は今は無い。代わりにschema=を使う。 | |
df2_std = pl.DataFrame(scaler.fit_transform(df2.to_numpy()), schema=df2.columns) | |
display(df2_std) | |
display(df2_std.describe()) # 各科目のmin,maxが0,1になっているはず。 | |
# %% | |
# 【85】 | |
# dfのfare列の最大値、最小値の行名を取得 | |
print(ans[85]) # 解答表示 | |
df = initialize1() # 初期化 | |
display(df.filter(pl.col("fare") == pl.col("fare").min()).select("name", "fare")) | |
display(df.filter(pl.col("fare") == pl.col("fare").max()).select("name", "fare")) | |
# %% | |
# 【86】 | |
# dfのfare列の0、25、50、75、100パーセンタイルを取得 | |
print(ans[86]) # 解答表示 | |
df = initialize1() # 初期化 | |
display(df.select("fare").quantile(0)) | |
display(df.select("fare").quantile(0.25)) | |
display(df.select("fare").quantile(0.5)) | |
display(df.select("fare").quantile(0.75)) | |
display(df.select("fare").quantile(1)) | |
# %% | |
# 【87】 | |
# ①dfのage列の最頻値を取得 | |
# ②value_counts()にてage列の要素数を | |
# 確認し、①の結果の妥当性を確認 | |
print(ans[87]) # 解答表示 | |
df = initialize1() # 初期化 | |
display(df.select(pl.col("age").drop_nulls().mode())) | |
df.get_column("age").drop_nulls().value_counts().sort("counts", descending=True).head(5) | |
# %% | |
# 【88】 | |
# dfのsex列をラベルエンコーディングし、 | |
# dfの先頭5行を表示 | |
# (from sklearn.preprocessing import LabelEncoderをインポート) | |
print(ans[88]) # 解答表示 | |
df = initialize1() # 初期化 | |
# sklearn使わずこれでもよさそう | |
display( | |
df.with_columns( | |
pl.col("sex").cast(pl.Utf8).cast(pl.Categorical).to_physical() | |
).head(5) | |
) | |
# sklearn使う場合 | |
from sklearn.preprocessing import LabelEncoder | |
le = LabelEncoder() | |
df = df.with_columns(pl.Series(le.fit_transform(df.get_column("sex"))).alias("sex")) | |
df.head(5) | |
# %% | |
# 【89】 | |
# dfのsex列をOne-hotエンコーディングし、 | |
# dfの先頭5行を表示 | |
print(ans[89]) # 解答表示 | |
df = initialize1() # 初期化 | |
df.to_dummies("sex").head(5) | |
# %% | |
# 【90】ラベルエンコーディング | |
# df_copyのsexとembarked列をラベルエンコーディング | |
# (from sklearn.preprocessing import LabelEncoderをインポート) | |
# (df_copyはdfをコピーしたもの) | |
print(ans[90]) # 解答表示 | |
df = initialize1() # 初期化 | |
df_copy = df.clone() | |
from sklearn.preprocessing import LabelEncoder | |
le = LabelEncoder() | |
lsex = le.fit_transform(df.select("sex").to_series()) | |
lembarked = le.fit_transform(df.select("embarked").to_series()) | |
df_copy = df_copy.with_columns(pl.Series("sex", lsex), pl.Series("embarked", lembarked)) | |
df_copy.head() | |
# %% | |
# 【91】欠損値確認 | |
# df_copyの欠損値を確認 | |
print(ans[91]) # 解答表示 | |
df_copy.null_count() | |
# %% | |
# 【92】欠損値補完 | |
# df_copyのage、fare列の欠損値を各列の平均値で補完 | |
print(ans[92]) # 解答表示 | |
df_copy = df_copy.with_columns( | |
pl.col("age").fill_null(pl.col("age").mean()), | |
pl.col("fare").fill_null(pl.col("fare").mean()), | |
) | |
df_copy.null_count() | |
# %% | |
# 【93】不要列の削除 | |
# df_copyの中で機械学習で使用しない不要な行を削除 | |
# (name, ticket, cabin, boat, body, home.destを削除) | |
print(ans[93]) # 解答表示 | |
df_copy = df_copy.drop("name", "ticket", "cabin", "boat", "body", "home.dest") | |
df_copy.head(1) | |
# %% | |
# 【94】ndarray形式への変換 | |
# ①df_copyのpclass、age、sex、fare、embarkedの列を抽出し、ndarray形式に変換 | |
# ②df_copyのsurvivedの列を抽出し、ndarray形式に変換 | |
# (①をfeatures、②をtargetという変数にそれぞれ格納) | |
print(ans[94]) # 解答表示 | |
features = df_copy.select("pclass", "age", "sex", "fare", "embarked").to_numpy() | |
target = df_copy.select("survived").to_numpy() | |
# %% | |
# 【95】学習データとテストデータに分割 | |
# 【94】で作成したfeatrues、targetを学習データとテストデータに分割 | |
# (from sklearn.model_selection import train_test_splitをインポート) | |
# ※分割時のパラメータは次を指定 test_size=0.3 random_state=0 | |
print(ans[95]) # 解答表示 | |
from sklearn.model_selection import train_test_split | |
(features, test_X, target, test_y) = train_test_split( | |
features, target, test_size=0.3, random_state=0 | |
) | |
# %% | |
# 【96】学習の実行 | |
# 学習データ(features、target)を用いランダムフォレストにて学習を実行 | |
# (from sklearn.ensemble import RandomForestClassifierをインポート) | |
# ※パラメータは次を指定 n_estimators=100 random_state=0 | |
print(ans[96]) # 解答表示 | |
from sklearn.ensemble import RandomForestClassifier | |
rfc = RandomForestClassifier(n_estimators=100, random_state=0) | |
rfc.fit(features, target) | |
# %% | |
# 【97】予測の実行 | |
# test_Xデータの乗客の生存を予測 | |
print(ans[97]) # 解答表示 | |
pred = rfc.predict(test_X) | |
# %% | |
# 【98】予測精度の確認 | |
# 予測結果がtest_y(生存有無の答え)とどれぐらい | |
# 整合していたかを確認(評価指標はaccuracy) | |
# (from sklearn.metrics import accuracy_scoreをインポート) | |
print(ans[98]) # 解答表示 | |
from sklearn.metrics import accuracy_score | |
accuracy_score(pred, test_y) | |
# %% | |
# 【99】重要度の確認 | |
# 学習における各列(特徴量)の | |
# 重要度を表示 | |
print(ans[99]) # 解答表示 | |
pl.DataFrame( | |
{ | |
"feature": ["pclass", "age", "sex", "fare", "embarked"], | |
"importance": rfc.feature_importances_, | |
} | |
) | |
# %% | |
# 【100】予測結果のcsv出力 | |
# test_Xの予測結果をcsvでoutputフォルダに出力(ファイル名は「submission.csv」) | |
# (headerは不要) | |
print(ans[100]) # 解答表示 | |
pl.from_numpy(pred).write_csv("../output/submission.csv", has_header=False) | |
# %% [markdown] | |
# # ノックお疲れ様でした |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
ファイル追加