Andrea Amantini / Jul 02 2019
Clojure + Python
apt-get update &&\ apt-get install libpython3.6-dev python3-pip &&\ pip3 install numpy pandas
(require [libpython-clj.python :as py]) (require [camel-snake-kebab.core :as csk]) (require [camel-snake-kebab.extras :as cske]) (require [clojure.core.memoize :as m]) ;(require '[oz.core :as oz]) (py/initialize!)
:ok
{:deps {org.clojure/clojure {:mvn/version "1.10.1"} compliment {:mvn/version "0.3.9"} cnuernber/libpython-clj {:mvn/version "0.10"} camel-snake-kebab {:mvn/version "0.4.0"} org.clojure/core.memoize {:mvn/version "0.7.2"} _#_metasoarous/oz {:mvn/version "1.5.6"}}}
deps.edn
Extensible Data Notation
(require [libpython-clj.python :as py]) (require [camel-snake-kebab.core :as csk]) (require [camel-snake-kebab.extras :as cske]) (require [clojure.core.memoize :as m]) (py/initialize!)
:ok
(defn plot [spec] (with-meta spec {:nextjournal/viewer "vega-lite"})) (defonce pandas (py/import-module "pandas")) (defonce np (py/import-module "numpy")) (defonce builtins (py/import-module "builtins")) (def memo-key-converter (m/fifo csk/->snake_case_string {} :fifo/threshold 512)) (defn keyword->pyarg [m] (cske/transform-keys memo-key-converter m)) (defn key->arg [k] (if (keyword? k) (memo-key-converter k) k)) (defn read-csv [filename & [attrs]] (py/call-attr-kw pandas "read_csv" [filename] (keyword->pyarg attrs))) (def pokemon (read-csvpokemon.csv{:nrows 10}))
'user/pokemon
Since we cannot put metadata on a string value, we can return a map of the form
(defn show [obj] (let [csv (py/call-attr obj "to_csv")] {:nextjournal.viewer/value csv :nextjournal.viewer/content-type "text/csv"}))
'user/show
or
(defn show' [obj] (let [csv (py/call-attr obj "to_csv")] {:nextjournal.viewer/value csv :nextjournal/viewer "table"}))
'user/show'
(defn head [df-or-series & [n]] (py/call-attr df-or-series "head" (or n 5)))
'user/head
(defn pandas->clj [df-or-series] (map (into {} %) (vec (py/call-attr df-or-series "to_dict" "records"))))
'user/pandas->clj
(-> pokemon head show')
# | Name | Type 1 | Type 2 | HP | Attack | Defense | Sp. Atk | Sp. Def | Speed | Generation | Legendary | |
---|---|---|---|---|---|---|---|---|---|---|---|---|
0 | 1 | Bulbasaur | Grass | Poison | 45 | 49 | 49 | 65 | 65 | 45 | 1 | False |
1 | 2 | Ivysaur | Grass | Poison | 60 | 62 | 63 | 80 | 80 | 60 | 1 | False |
2 | 3 | Venusaur | Grass | Poison | 80 | 82 | 83 | 100 | 100 | 80 | 1 | False |
3 | 4 | Mega Venusaur | Grass | Poison | 80 | 100 | 123 | 122 | 120 | 80 | 1 | False |
4 | 5 | Charmander | Fire | 39 | 52 | 43 | 60 | 50 | 65 | 1 | False |
5 items
(-> pokemon head show)
# | Name | Type 1 | Type 2 | HP | Attack | Defense | Sp. Atk | Sp. Def | Speed | Generation | Legendary | |
---|---|---|---|---|---|---|---|---|---|---|---|---|
0 | 1 | Bulbasaur | Grass | Poison | 45 | 49 | 49 | 65 | 65 | 45 | 1 | False |
1 | 2 | Ivysaur | Grass | Poison | 60 | 62 | 63 | 80 | 80 | 60 | 1 | False |
2 | 3 | Venusaur | Grass | Poison | 80 | 82 | 83 | 100 | 100 | 80 | 1 | False |
3 | 4 | Mega Venusaur | Grass | Poison | 80 | 100 | 123 | 122 | 120 | 80 | 1 | False |
4 | 5 | Charmander | Fire | 39 | 52 | 43 | 60 | 50 | 65 | 1 | False |
5 items
(println pokemon)