Saddle: Scala Data Library
saddle.github.com
saddle.github.com
It might be worth adding an example to make it a bit more explicit in the documentation, such as:
import org.saddle.Vec._
Vec(1,2,3).median // Returns 2
Other than that, it looks pretty cool, I'll go use it right now. :)Edit: Formatting.
import org.saddle._
to get all the implicit goodness. I'll add a note.Is there something like this for Clojure? I guess I'll have to pick up scala too. Coursera here I come.
Probably Incanter which uses the Parallel Colt Java library - http://incanter.org/ | https://sites.google.com/site/piotrwendykier/software/parall...
Most of my colleagues do data analysis in Python given Numpy+SciPy. I like Python, but if possible, I'd rather do as much of my development in a single language, and I prefer Scala.
This library certainly does not replicate the extensive functionality offered in Python for data analysis, but it does have the potential to seed Scala development. I for one will be perusing the code this weekend, and picking an avenue for subsequent exploration.
Do we have performance information yet, even on some basic, common use cases?
Also, the docs mention EJML as the backend for Saddle's data structures--do you have any thoughts on using EJML?
Consider the following in Saddle:
val s1 = Series(vec.rand(10000), Index(Vec(array.randIntPos(10000)) % 100))
val s2 = Series(vec.rand(10000), Index(Vec(array.randIntPos(10000)) % 100))
clock { s1.join(s2, how=index.OuterJoin) }
This clocks in at 19ms on my machine after Hotspot kicks in.The equivalent pandas:
In [10]: ix1 = np.random.random_integers(0, 100, 10000)
In [11]: ix2 = np.random.random_integers(0, 100, 10000)
In [12]: df1 = DataFrame({'x' : np.random.rand(10000)}, ix1)
In [13]: df2 = DataFrame({'y' : np.random.rand(10000)}, ix2)
In [14]: %timeit df1.join(df2, how='outer')
10 loops, best of 3: 37.7 ms per loopWhile it's maybe 2x-4x slower than JNI wrapped ATLAS or MKL, for the cases I deal with, it just doesn't matter vs ease of use.
That said, it's LGPL, so I made it easy to swap out for other matrix libraries if you need.
val s = Series(Vec(1,2,3), Index(0,5,10))
This gives you s: org.saddle.Series[Int, Int] =
[3 x 1]
0 -> 1
5 -> 2
10 -> 3
Then, for instance, s(5,10)
res0: org.saddle.Series[Int,Int] =
[2 x 1]
5 -> 2
10 -> 3