Skip to content

Instantly share code, notes, and snippets.

@okotani
Last active December 26, 2023 07:56
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save okotani/5308b139af24457ed1cf08c4f6872180 to your computer and use it in GitHub Desktop.
Save okotani/5308b139af24457ed1cf08c4f6872180 to your computer and use it in GitHub Desktop.
初学者向けPolars100本ノック
# 参照元:初学者向け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]
# # ノックお疲れ様でした
@okotani
Copy link
Author

okotani commented Jul 29, 2023

ファイル追加

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment