✨
Python Pandas 使いの私のための Clojure Tablecloth のメモ
Pandasでやるあの操作をClojure Tablecloth ではどうすればいいのかメモしてます。
※完成品ではありません。適宜更新します。
import / require
pandas
import pandas
clojure
(ns sandbox
(:require [tech.v3.dataset :as ds]
[tech.v3.datatype.functional :as dfn]
[tablecloth.api :as tc]
[tech.v3.dataset.rolling :as ds-roll]))
read csv
pandas
df = pd.read_csv("https://raw.githubusercontent.com/plotly/datasets/refs/heads/master/stockdata.csv")
clojure
(def stocks
(tc/dataset "https://raw.githubusercontent.com/plotly/datasets/refs/heads/master/stockdata.csv"
{:dataset-name :stocks}))
data info
pandas
df.info()
clojure
(tc/info stocks)
write csv
pandas
df.to_csv("/tmp/df.csv")
clojure
(tc/write! stocks "/tmp/stocks.csv")
select columns
pandas
df[["Date", "MSFT"]]
clojure
(ds/select-columns stocks ["Date" "MSFT"])
rolling
pandas
df["MSFT_MA3"] = df["MSFT"].rolling(window=3).mean()
clojure
(ds-roll/rolling stocks
{:window-size 3
:relative-window-position :left}
{:msft-ma3 (ds-roll/mean "MSFT")})
-
https://techascent.github.io/tech.ml.dataset/tech.v3.dataset.rolling.html
-
:relative-window-position :left
:window-size のどの位置に計算したデータを入れるかを指定。- 例
(def x (ds/->dataset [{:b 10} {:b 20} {:b 30} {:b 40} {:b 50}])) ;; | :b | ;; |---:| ;; | 10 | ;; | 20 | ;; | 30 | ;; | 40 | ;; | 50 |
left
の場合、pandas と同じように window-size の最後に結果が入る(-> x (ds-roll/rolling {:window-size 3 :relative-window-position :left} {:mean (ds-roll/mean :b)})) ;; _unnamed [5 2]: ;; | :b | :mean | ;; |---:|------------:| ;; | 10 | 10.00000000 | ;; | 20 | 13.33333333 | ;; | 30 | 20.00000000 | ←上3行の結果がここに入る ;; | 40 | 30.00000000 | ;; | 50 | 40.00000000 |
right
の場合(-> x (ds-roll/rolling {:window-size 3 :relative-window-position :right} {:mean (ds-roll/mean :b)})) ;; _unnamed [5 2]: ;; | :b | :mean | ;; |---:|------------:| ;; | 10 | 20.00000000 |←下3行の結果がここに入る ;; | 20 | 30.00000000 | ;; | 30 | 40.00000000 | ;; | 40 | 46.66666667 | ;; | 50 | 50.00000000 |
center
の場合(-> x (ds-roll/rolling {:window-size 3 :relative-window-position :center} {:mean (ds-roll/mean :b)})) ;; _unnamed [5 2]: ;; | :b | :mean | ;; |---:|------------:| ;; | 10 | 13.33333333 | ;; | 20 | 20.00000000 |←上下3行の結果が真ん中に入る ;; | 30 | 30.00000000 | ;; | 40 | 40.00000000 | ;; | 50 | 46.66666667 |
rename columns
pandas
df.rename(columns={"MSFT": "MicroSoft"})
clojure
(ds/rename-columns stocks {"MSFT" :msft})
column operation
pandas
df["MSFT-GSPC"] = df["MSFT"] / df["GSPC"]
clojure
(tc// stocks :msft-gspc ["MSFT" "GSPC"])
- https://scicloj.github.io/tablecloth/#column-operations
-
tc//
は、column api と呼ばれている(らしい) - https://github.com/scicloj/tablecloth/blob/master/src/tablecloth/column/api.clj ここにあるものなら渡せる(みたい)
sort-by / order-by
pandas
df.sort_values(by="Date") # 小さい方/古い方から順
df.sort_values(by="Date", ascending=False) # default True
clojure
(tc/order-by stocks "Date" ) ;; 小さい方/古い方から順
(tc/order-by stocks "Date" :desc) ;; 逆
drop duplicate
pandas
df.drop_duplicates()
df.drop_duplicates(subset = ["DATE"])
clojure
(tc/unique-by stocks)
(tc/unique-by stocks "Date")
(tc/unique-by stocks ["Date" "MSFT"])
fill zero
pandas
df['A'].replace(to_replace=0, method='ffill')
clojure
(defn fill-zero [data column]
(->
(tc/map-columns data column [column] #(if (= % 0.0) nil %))
(tc/replace-missing [column] :down)))
- ゼロは一旦 nil にしないとだめ
head / tail
pandas
df.head()
df.tail()
clojure
(tc/head DS)
(tc/tail DS)
(tc/tail DS 10)
一つのコラムデータに対する操作
pandas
df["MSFT"] - 1
clojure
(tc/update-columns DS :a #(dfn/- % 1)) ;; 特定のコラム
(tc/update-columns DS :all #(dfn/- % 1)) ;; 全てに対して
コラムの型変換
pandas
df.astype('int32').dtypes
df.astype({'col1': 'int32'}).dtypes
clojure
(-> DS
(tc/convert-types :V1 :float64)
(tc/info :columns))
<!--
read csv
pandas
clojure
-->
Discussion