まだ Pandas🐼 使ってんの!? ⭐️Polars🐻‍❄️⭐️ だろ今は!! その1

# 1. はじめに
遅まきながら、[⭐️Polars🐻‍❄️⭐️](https://pola.rs/) を触ってみたところ、何やら良すぎた! コレ知らんヤツが、データサイエンティスト!? チャンチャラおかしいわ、笑てまうやんけ!! とまで思ってしまったので、簡単に、Tipsをまとめてみました。[Pandas🐼](https://pandas.pydata.org/) は使えるけどね、という方々に向けて、両者のコードを並べて書いています。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/195509/6a34f012-0b97-efb4-2adc-a641cbd3a16c.png)

(Kaggle ノートブック ["Let's Play with 🌙 Polars 🐻‍❄️ & 🌙 Pandas 🐼"](https://www.kaggle.com/code/acchiko/let-s-play-with-polars-pandas)からの引用)

# 2. 何が良いんだい??
⭐️Polars🐻‍❄️⭐️ の何が良いんだい?? と思った方々に向けて、良いところをつらつらと書き綴っておきます。
- とにかく早い。
    - データによるが、以下の通り、数十倍にも達し得る。
    - データの規模が大きいほど、Pandas🐼 との差が顕著になる。
- メモリに乗りきらない大規模なデータも取り扱える。
    - Pandas🐼 でもできないことはないが、より簡単な短いコードで同じことがやれる。
      (Pandas🐼 は無駄に大きなメモリを使うので、大規模なデータを扱いづらい。)
- 直感的に分かりやすい。
    - Pandas🐼 よりも直感的に分かりやすい書き方で書ける。
    - indexみたいなややこしい仕組みもない。


![スクリーンショット 2024-05-25 17.07.57.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/195509/9689d1db-88c0-f8bb-fe44-dce694c1adca.png)

![スクリーンショット 2024-05-25 17.08.46.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/195509/6f77b647-a29b-de6a-1dc4-e9c94a93bfd7.png)

([Polars HP](https://pola.rs/)からの引用)


# 3. ⭐️Polars🐻‍❄️⭐️ の10Tips
では、本題です。ここでは、過去に、Kaggleで開催されたコンペ ["Home Credit Default Risk"](https://www.kaggle.com/competitions/home-credit-default-risk) のデータセットを、⭐️Polars🐻‍❄️⭐️を使って処理してみます。その中で、以下の10個のTipsを紹介していきたいと思います。比較のため、Pandas🐼 のコードも併せて記載してあります。

- #001 ファイルを読み込む。
- #002 名前を指定して列を切り出す。
- #003 名前の一部を指定して列を切り出す。
- #004 データの型を指定して列を切り出す。
- #005 行の番号を指定して行を切り出す。
- #006 条件を指定して行を切り出す。
- #007 数値の列の基本的な統計量を求める。
- #008 数値以外の列のユニークな値毎の行の数を数える。
- #009 欠損値の数を数える。
- #010 欠損値を埋めあわせる。

## #000 まずは準備。
まず、必要なパッケージをインストールして、インポートします。

```python
# ⭐️Polars🐻‍❄️⭐️
%pip install -Uq polars
import polars as pl
import polars.selectors as cs
```

```python
# Pandas🐼
import pandas as pd
```

これで、準備は完了です。


## #001 ファイルを読み込む。
ファイルを読み込みます。

```python
# ⭐️Polars🐻‍❄️⭐️
path_to_your_file = "/kaggle/input/home-credit-default-risk/application_train.csv"
df_pl = pl.read_csv(path_to_your_file)
df_pl
```

```python
# Pandas🐼
path_to_your_file = "/kaggle/input/home-credit-default-risk/application_train.csv"
df_pd = pd.read_csv(path_to_your_file)
df_pd
```

## #002 名前を指定して列を切り出す。
名前を指定して、列を切り出してみます。ここでは、例として、`SK_ID_CURR`、`TARGET`という名前の列を切り出してみます。

```python
# ⭐️Polars🐻‍❄️⭐️
df_pl.select(pl.col(["SK_ID_CURR", "TARGET"]))
```

```python
# Pandas🐼
df_pd[["SK_ID_CURR", "TARGET"]]
```


## #003 名前の一部を指定して列を切り出す。
名前の一部を指定して、列を切り出してみます(正規表現を使った曖昧検索。正規表現が気になってきた方は、一度ググってみましょう。)。ここでは、例として、列の名前に`CREDIT_BUREAU`というキーワードを含む列を切り出してみます。

```python
# ⭐️Polars🐻‍❄️⭐️
df_pl.select(pl.col(r"^.*CREDIT_BUREAU.*$"))
```

```python
# Pandas🐼
df_pd.filter(regex=r"^.*CREDIT_BUREAU.*$")
```


## #004 データの型を指定して列を切り出す。
データの型を指定して、列を切り出してみます。ここでは、例として、文字列の値を含む列を切り出してみます。

```python
# ⭐️Polars🐻‍❄️⭐️
df_pl.select(cs.string())
```

```python
# Pandas🐼
df_pd.select_dtypes(include="object")
```

## #005 行の番号を指定して行を切り出す。
行の番号を指定して、行を切り出してみます。ここでは、例として、2行目から7行目を切り出してみます。

```python
# ⭐️Polars🐻‍❄️⭐️
df_pl.with_row_index().filter(pl.col("index").is_between(2, 7))
```

```python
# Pandas🐼
df_pd.iloc[2:7+1]
```

## #006 条件を指定して行を切り出す。
条件を指定して、行を切り出してみます。ここでは、例として、`AMT_INCOME_TOTAL` が `1_000_000` 以上の行を切り出してみます。

```python
# ⭐️Polars🐻‍❄️⭐️
df_pl.filter(pl.col("AMT_INCOME_TOTAL") >= 1_000_000)
```

```python
# Pandas🐼
df_pd[df_pd["AMT_INCOME_TOTAL"] >= 1_000_000]
```

## #007 数値の列の基本的な統計量を求める。
数値の列の基本的な統計量(平均、分散、分位数、等)を求めてみます。

```python
# ⭐️Polars🐻‍❄️⭐️
df_pl.select(cs.numeric()).describe()
```

```python
# Pandas🐼
df_pd.select_dtypes(include="number").describe()
```

## #008 数値以外の列のユニークな値毎の行の数を数える。
数値以外の列のユニークな値毎に行の数を数えてみます。

```python
# ⭐️Polars🐻‍❄️⭐️
f_sliced = df_pl.select(~cs.numeric())
for col in df_sliced.columns:
    with pl.Config(tbl_rows=1000):
        print(df_sliced.select(pl.col(col).value_counts()))
        print()
```

```python
# Pandas🐼
df_sliced = df_pd.select_dtypes(exclude="number")
for col in df_sliced.columns:
    print(df_sliced[col].value_counts(dropna=False))
    print()
```

## #009 欠損値の数を数える。
列毎に、欠損値の数を数えてみます。ここでは、より分かりやすくするため、値の欠損がある列だけを取り出し、グラフの形で表示するようにしています。

```python
# ⭐️Polars🐻‍❄️⭐️
plt.figure(figsize=(8, 16))
sns.barplot(data=df_pl.null_count().melt(value_name="num_missing_values").filter(pl.col("num_missing_values") > 0),
            y="variable",
            x="num_missing_values",
            hue="variable")
plt.show()
```

```python
# Pandas🐼
df_missing_values = df_pd.isna().sum()
df_missing_values = df_missing_values[df_missing_values > 0]
plt.figure(figsize=(8, 16))
sns.barplot(y=df_missing_values.index,
            x=df_missing_values.values,
            hue=df_missing_values.index)
plt.show()
```

## #010 欠損値を埋めあわせる。
欠損値を埋め合わせてみます。ここでは、例として、列 `AMT_REQ_CREDIT_BUREAU_YEAR` の値を、① 定数 `999` もしくは ② 中央値 で埋め合わせてみます。

```python
# ⭐️Polars🐻‍❄️⭐️
df_pl = df_pl.with_columns(
    pl.col("AMT_REQ_CREDIT_BUREAU_YEAR").fill_null(pl.lit(999)).name.suffix("_filled_with_constant"),
    pl.col("AMT_REQ_CREDIT_BUREAU_YEAR").fill_null(pl.median("AMT_REQ_CREDIT_BUREAU_YEAR")).name.suffix("_filled_with_median"),
)
df_pl.select(pl.col(r"^.*AMT_REQ_CREDIT_BUREAU_YEAR.*$"))
```

```python
# Pandas🐼
median = df_pd["AMT_REQ_CREDIT_BUREAU_YEAR"].median()
df_pd["AMT_REQ_CREDIT_BUREAU_YEAR_filled_with_constant"] = df_pd["AMT_REQ_CREDIT_BUREAU_YEAR"].fillna(value=999)
df_pd["AMT_REQ_CREDIT_BUREAU_YEAR_filled_with_median"] = df_pd["AMT_REQ_CREDIT_BUREAU_YEAR"].fillna(value=median)
df_pd.filter(regex=r"^.*AMT_REQ_CREDIT_BUREAU_YEAR.*$")
```

以上、10個のTipsでした。本当はもうちょっとあるんだけどね。というか、Polarsの本当の良いところは、まだ、他にあるんだけどね(Lazyとか、Lazyとか、・・・。)。それは、また、次回か、次次回で紹介したいと思います。


# 4. 参考
もしか、⭐️Polars🐻‍❄️⭐️ ラブ😍 になった方が居れば、こちらも、参考になりますので、眺めてみて下さい。大半は、英語ですが、字幕も出ますし、巷に翻訳してくれるソフトもたくさんあります。近くに、英語が分かる方がいらっしゃれば、翻訳をお願いしてみるのも一興です。この辺りを覚えられたら、一端のデータサイエンティストに一歩近づくことができます。ぜひ、見てみて下さい。

## ✏︎ [Polars user guide](https://docs.pola.rs/)
⭐️Polars🐻‍❄️⭐️ のユーザーガイドです。ここにある内容を全て写経したら、もはや、他は見なくても良いくらいです。英語ですが、すごく分かりやすいです。ロジカル、かつ、簡単に書いてあるので、英語分からなくても、コードを実行しながら追いかけていけば、余裕で理解できてしまいます。

## ✏︎ [Ritchie Vink - Keynote Polars | PyCon Lithuania 2024](https://www.youtube.com/watch?v=GOOYbl3cqlc)
リトアニアで開催された、PyConの動画です。⭐️Polars🐻‍❄️⭐️ の著者、Ritchie Vinkさんが、素晴らしい Keynote で ⭐️Polars🐻‍❄️⭐️ を紹介してくれています。ご本人に興味がある方、ユーザーガイドはまだムズイ、という方、ぜひ、見てみて下さい。 

## ✏︎ [Let's Play with 🌙 Polars 🐻‍❄️ & 🌙 Pandas 🐼](https://www.kaggle.com/code/acchiko/let-s-play-with-polars-pandas)
この記事のベースとなっている、Kaggleのノートブックです。実際に、コードを実行して結果を見てみたい方は、これをコピーして、自身で動かしてみましょう。

## ✏︎ [Thomas Bierhance: Polars - make the switch to lightning-fast dataframes](https://www.youtube.com/watch?v=CtkMzCIXOWk)
ドイツで開催された、PyConの動画です。その道のプロである、Thomas Bierhanceさんが、実際の仕事で、⭐️Polars🐻‍❄️⭐️ を導入した際に分かったメリットや(売り物になるようなレベルの)コードの書き方の例 などを、紹介してくれています。⭐️Polars🐻‍❄️⭐️ の基本が分かってきて、さあ、仕事で使っていこう、と思ってきた方にオススメの動画です。私も、彼のプレゼンから、コードの書き方を学びました。

## ✏︎ [PyCon JP](https://2024.pycon.jp/) 
PyConは、日本でも開催されています。 ⭐️Polars🐻‍❄️⭐️ が出てくるかは分かりませんが、折りを見て、参加してみるのも一興です。直接、社外の優秀な人の話を聞くと、刺激を受けて、あなたの成長につながります。



# 5. 最後に
生き物は必ず死を迎えます。それも、いつ訪れるのかわかりません。明日ミサイルが飛んでくるかも。時間は有限です。その中で、如何にやりたいことを成し遂げるのか、その鍵は時間の使い方にあります。計算機にやれる仕事はすべて、計算機にやってもらいましょう。そして、自分にしかできないこと、やりたいことをやりましょう。大事なことは、とにかく、自分のやりたいこと、楽しいことをやって、面白おかしく生きていくことです。