diff --git a/deps.edn b/deps.edn index 82cb9b9..1948659 100644 --- a/deps.edn +++ b/deps.edn @@ -1,6 +1,7 @@ {:extra-paths ["data"] :deps {org.clojure/clojure {:mvn/version "1.10.3"} techascent/tech.ml.dataset {:mvn/version "6.002"} - + meander/epsilon {:mvn/version "0.0.602"} ;; generateme/fastmath {:mvn/version "2.1.0"} - }} + } + :aliases {:test {:extra-deps {midje/midje {:mvn/version "1.9.9"}}}}} diff --git a/src/tablecloth/api.clj b/src/tablecloth/api.clj index 7630cd7..63cb95e 100644 --- a/src/tablecloth/api.clj +++ b/src/tablecloth/api.clj @@ -1,6 +1,10 @@ (ns tablecloth.api - (:refer-clojure :exclude [group-by drop concat rand-nth first last shuffle]) - (:require [tech.v3.datatype.export-symbols :as exporter])) + (:refer-clojure :exclude [group-by drop concat rand-nth first last shuffle + max min + - * / <= < >= > = not= bit-xor unsigned-bit-shift-right quot bit-test + bit-and rem bit-or bit-flip bit-shift-left bit-clear bit-shift-right bit-set + bit-and-not bit-not identity and even? neg? not odd? or pos? zero?]) + (:require [tech.v3.datatype.export-symbols :as exporter] + [tablecloth.api.operators :as op])) (exporter/export-symbols tech.v3.datatype clone) @@ -160,3 +164,104 @@ (unmark-group) ~@r (mark-as-group))) + +;; operators + +(exporter/export-symbols tablecloth.api.operators + * + + + - + / + = + < + <= + > + >= + abs + acos + and + asin + atan + atan2 + bit-and + bit-and-not + bit-clear + bit-flip + bit-not + bit-or + bit-set + bit-shift-left + bit-shift-right + bit-test + bit-xor + cbrt + ceil + cos + cosh + cummax + cummin + cumprod + cumsum + descriptive-statistics + emax + emin + eq + even? + exp + expm1 + finite? + floor + get-significand + hypot + identity + ieee-remainder + infinite? + kendalls-correlation + kurtosis + log + log10 + log1p + logistic + mathematical-integer? + max + mean + median + min + nan? + neg? + next-down + next-up + not + not= + not-eq + odd? + or + pearsons-correlation + percentiles + pos? + pow + quartile-1 + quartile-3 + quartile-outlier-fn + quartiles + quot + rem + rint + round + signum + sin + sinh + skew + spearmans-correlation + sq + sqrt + standard-deviation + sum + tan + tanh + to-degrees + to-radians + ulp + unsigned-bit-shift-right + variance + zero?) diff --git a/src/tablecloth/api/operators.clj b/src/tablecloth/api/operators.clj new file mode 100644 index 0000000..a6867be --- /dev/null +++ b/src/tablecloth/api/operators.clj @@ -0,0 +1,46 @@ +(ns tablecloth.api.operators + (:refer-clojure :exclude [max min + - * / bit-xor unsigned-bit-shift-right quot bit-test + bit-and rem bit-or bit-flip bit-shift-left bit-clear bit-shift-right bit-set + bit-and-not bit-not identity < <= > >= = not= and even? neg? not odd? or pos? zero?]) + (:require + [tech.v3.datatype.unary-op :as unary-op] + [tech.v3.datatype.binary-op :as binary-op] + [tech.v3.datatype.unary-pred :as unary-pred] + [tech.v3.datatype.binary-pred :as binary-pred] + [tech.v3.datatype.functional :as dfn] + [tech.v3.datatype.export-symbols :as exporter] + [tablecloth.api.utils :as u])) + +(u/defalias = tech.v3.datatype.functional/eq) +(u/defalias not= tech.v3.datatype.functional/not-eq) +(u/defalias emax tech.v3.datatype.functional/reduce-max) +(u/defalias emin tech.v3.datatype.functional/reduce-min) + +(exporter/export-symbols + tech.v3.datatype.functional + sum + cumsum + cummin + cummax + cumprod + descriptive-statistics + variance + standard-deviation + median + skew + mean + kurtosis + quartile-1 + quartile-3 + pearsons-correlation + spearmans-correlation + kendalls-correlation + percentiles + quartiles + quartile-outlier-fn + ;; (->> (concat (keys binary-op/builtin-ops) (keys unary-op/builtin-ops) + ;; (keys binary-pred/builtin-ops) (keys unary-pred/builtin-ops)) + ;; (map (comp symbol name)) + ;; (distinct) + ;; (sort)) + * + - / < <= > >= abs acos and asin atan atan2 bit-and bit-and-not bit-clear bit-flip bit-not bit-or bit-set bit-shift-left bit-shift-right bit-test bit-xor cbrt ceil cos cosh eq even? exp expm1 finite? floor get-significand hypot identity ieee-remainder infinite? log log10 log1p logistic mathematical-integer? max min nan? neg? next-down next-up not not-eq odd? or pos? pow quot rem rint round signum sin sinh sq sqrt tan tanh to-degrees to-radians ulp unsigned-bit-shift-right zero?) diff --git a/src/tablecloth/api/utils.clj b/src/tablecloth/api/utils.clj index 5ad0667..41c6d7e 100644 --- a/src/tablecloth/api/utils.clj +++ b/src/tablecloth/api/utils.clj @@ -175,3 +175,19 @@ ([ds f parallel?] (ds/add-or-update-column ds :data ((if parallel? pmap map) f (ds :data))))) +;; https://github.com/ptaoussanis/encore/blob/master/src/taoensso/encore.cljc#L406 +(defmacro defalias + "Defines an alias for qualified source symbol, preserving its metadata (clj only): + (defalias my-map-alias clojure.core/map) + + Cannot alias Cljs macros. + Changes to source are not automatically applied to alias." + ;; TODO Any way to reliably preserve cljs metadata? See #53, commit 2a63a29, etc. + + ([ src ] `(defalias ~(symbol (name src)) ~src nil)) + ([sym src ] `(defalias ~sym ~src nil)) + ([sym src attrs] + (let [attrs (if (string? attrs) {:doc attrs} attrs)] ; Back compatibility + `(let [attrs# (conj (select-keys (meta (var ~src)) [:doc :arglists :private :macro]) ~attrs)] + (alter-meta! (def ~sym @(var ~src)) conj attrs#) + (var ~sym))))) diff --git a/test/tablecloth/api/operators_test.clj b/test/tablecloth/api/operators_test.clj new file mode 100644 index 0000000..61bae32 --- /dev/null +++ b/test/tablecloth/api/operators_test.clj @@ -0,0 +1,107 @@ +(ns tablecloth.api.operators-test + (:require [tablecloth.api :as api] + [tablecloth.api.operators :as op] + [midje.sweet :refer [facts fact =>]])) + +(def data (vec (repeatedly 100 (fn [] {:a (- (rand) 0.5) + :b (- (rand) 0.5)})))) +(def ds (api/dataset data)) + +(facts "no operator should return exceptions and that is enough for now" + (fact (some? (api/* (api/column ds :a) (api/column ds :b))) => true) + (fact (some? (api/+ (api/column ds :a) (api/column ds :b))) => true) + (fact (some? (api/- (api/column ds :a) (api/column ds :b))) => true) + (fact (some? (api// (api/column ds :a) (api/column ds :b))) => true) + (fact (some? (api/< (api/column ds :a) (api/column ds :b))) => true) + (fact (some? (api/<= (api/column ds :a) (api/column ds :b))) => true) + (fact (some? (api/> (api/column ds :a) (api/column ds :b))) => true) + (fact (some? (api/>= (api/column ds :a) (api/column ds :b))) => true) + (fact (some? (api/= (api/column ds :a) (api/column ds :b))) => true) + (fact (some? (api/abs (api/column ds :a))) => true) + (fact (some? (api/acos (api/column ds :a))) => true) + (fact (some? (api/and (api/column ds :a) (api/column ds :a))) => true) + (fact (some? (api/asin (api/column ds :a))) => true) + (fact (some? (api/atan (api/column ds :a))) => true) + (fact (some? (api/atan2 (api/column ds :a) (api/column ds :b))) => true) + ;; (fact (some? (api/bit-and (api/column ds :a) (api/column ds :b)))) + ;; (fact (some? (api/bit-and-not (api/column ds :a) (api/column ds :b)))) + ;; (fact (some? (api/bit-clear (api/column ds :a) (api/column ds :b)))) + ;; (fact (some? (api/bit-flip (api/column ds :a)))) + ;; (fact (some? (api/bit-not (api/column ds :a)))) + ;; (fact (some? (api/bit-or (api/column ds :a)))) + ;; (fact (some? (api/bit-set (api/column ds :a)))) + ;; (fact (some? (api/bit-shift-left (api/column ds :a)))) + ;; (fact (some? (api/bit-shift-right (api/column ds :a)))) + ;; (fact (some? (api/bit-test (api/column ds :a)))) + ;; (fact (some? (api/bit-xor (api/column ds :a)))) + (fact (some? (api/cbrt (api/column ds :a))) => true) + (fact (some? (api/ceil (api/column ds :a))) => true) + (fact (some? (api/cos (api/column ds :a))) => true) + (fact (some? (api/cosh (api/column ds :a))) => true) + (fact (some? (api/cummax (api/column ds :a))) => true) + (fact (some? (api/cummin (api/column ds :a))) => true) + (fact (some? (api/cumprod (api/column ds :a))) => true) + (fact (some? (api/cumsum (api/column ds :a))) => true) + (fact (some? (api/descriptive-statistics (api/column ds :a))) => true) + (fact (some? (api/emin (api/column ds :a))) => true) + (fact (some? (api/emax (api/column ds :a))) => true) + (fact (some? (api/eq (api/column ds :a) (api/column ds :b))) => true) + ;; (fact (some? (api/even? (api/dataset {:a [1 2 3 4]}))) => true) + (fact (some? (api/exp (api/column ds :a))) => true) + (fact (some? (api/expm1 (api/column ds :a))) => true) + (fact (some? (api/finite? (api/column ds :a))) => true) + (fact (some? (api/floor (api/column ds :a))) => true) + (fact (some? (api/get-significand (api/column ds :a))) => true) + (fact (some? (api/hypot (api/column ds :a) (api/column ds :b))) => true) + (fact (some? (api/identity (api/column ds :a))) => true) + (fact (some? (api/ieee-remainder (api/column ds :a) (api/column ds :b))) => true) + (fact (some? (api/infinite? (api/column ds :a))) => true) + (fact (some? (api/kendalls-correlation (api/column ds :a) (api/column ds :b))) => true) + (fact (some? (api/kurtosis (api/column ds :a))) => true) + (fact (some? (api/log (api/column ds :a))) => true) + (fact (some? (api/log10 (api/column ds :a))) => true) + (fact (some? (api/log1p (api/column ds :a))) => true) + (fact (some? (api/logistic (api/column ds :a))) => true) + (fact (some? (api/mathematical-integer? (api/column ds :a))) => true) + (fact (some? (api/max (api/column ds :a) (api/column ds :b))) => true) + (fact (some? (api/mean (api/column ds :a))) => true) + (fact (some? (api/median (api/column ds :a))) => true) + (fact (some? (api/min (api/column ds :a) (api/column ds :b))) => true) + (fact (some? (api/nan? (api/column ds :a))) => true) + (fact (some? (api/neg? (api/column ds :a))) => true) + (fact (some? (api/next-down (api/column ds :a))) => true) + (fact (some? (api/next-up (api/column ds :a))) => true) + (fact (some? (api/not (api/column ds :a))) => true) + (fact (some? (api/not= (api/column ds :a) (api/column ds :b))) => true) + (fact (some? (api/not-eq (api/column ds :a) (api/column ds :b))) => true) + ;; (fact (some? (api/odd? (api/column ds :a) (api/column ds :b))) => true) + (fact (some? (api/or (api/column ds :a) (api/column ds :b))) => true) + (fact (some? (api/pearsons-correlation (api/column ds :a) (api/column ds :b))) => true) + (fact (some? (api/percentiles (api/abs (api/* 100 (api/column ds :a))) (api/column ds :b))) => true) + (fact (some? (api/pos? (api/column ds :a))) => true) + (fact (some? (api/pow (api/column ds :a) 2.0)) => true) + (fact (some? (api/quartile-1 (api/column ds :a))) => true) + (fact (some? (api/quartile-3 (api/column ds :a))) => true) + ;; (fact (some? (api/quartile-outlier-fn (api/column ds :a)))) + (fact (some? (api/quartiles (api/column ds :a))) => true) + (fact (some? (api/quot (api/column ds :a) 0.01)) => true) + (fact (some? (api/rem (api/column ds :a) 0.01)) => true) + (fact (some? (api/rint (api/column ds :a))) => true) + (fact (some? (api/round (api/column ds :a))) => true) + (fact (some? (api/signum (api/column ds :a))) => true) + (fact (some? (api/sin (api/column ds :a))) => true) + (fact (some? (api/sinh (api/column ds :a))) => true) + (fact (some? (api/skew (api/column ds :a))) => true) + (fact (some? (api/spearmans-correlation (api/column ds :a) (api/column ds :b))) => true) + (fact (some? (api/sq (api/column ds :a))) => true) + (fact (some? (api/sqrt (api/column ds :a))) => true) + (fact (some? (api/standard-deviation (api/column ds :a))) => true) + (fact (some? (api/sum (api/column ds :a))) => true) + (fact (some? (api/tan (api/column ds :a))) => true) + (fact (some? (api/tanh (api/column ds :a))) => true) + (fact (some? (api/to-degrees (api/column ds :a))) => true) + (fact (some? (api/to-radians (api/column ds :a))) => true) + (fact (some? (api/ulp (api/column ds :a))) => true) + ;; (fact (some? (api/unsigned-bit-shift-right (api/column ds :a)))) + (fact (some? (api/variance (api/column ds :a))) => true) + (fact (some? (api/zero? (api/column ds :a))) => true))