Skip to content

Commit 80dfc9f

Browse files
committed
stats
1 parent ae6454a commit 80dfc9f

File tree

6 files changed

+319
-71
lines changed

6 files changed

+319
-71
lines changed

src/main/scala/qnt/bz/DataFrame.scala

Lines changed: 40 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -130,6 +130,20 @@ class DataFrame[R, C, @specialized(Double, Int, Float, Long) V]
130130

131131
override def locRange(start: R, end: R, step: Int, keepStart: Boolean, keepEnd: Boolean, round: Boolean)
132132
: DataFrame[R, C, V] = iloc(rowIdx.locRange(start, end, step, keepStart, keepEnd, round).slices)
133+
134+
def iget(ci: Int): Series[C, V] = {
135+
var d = data match {
136+
case d: DenseMatrix[V] => d.apply(::, ci);
137+
case d: SliceMatrix[Int, Int, V] => d.apply(::, ci)
138+
case _ => ???
139+
}
140+
Series(colIdx, d)
141+
}
142+
143+
def get(c: C): Series[C, V] = {
144+
var i = colIdx.hashIndexOfUnsafe(c)
145+
iget(i)
146+
}
133147
}
134148

135149
object colOps extends Slice1dOps[C, DataFrame[R, C, V]] {
@@ -144,6 +158,21 @@ class DataFrame[R, C, @specialized(Double, Int, Float, Long) V]
144158

145159
override def locRange(start: C, end: C, step: Int, keepStart: Boolean, keepEnd: Boolean, round: Boolean)
146160
: DataFrame[R, C, V] = iloc(colIdx.locRange(start, end, step, keepStart, keepEnd, round).slices)
161+
162+
163+
def iget(ri: Int): Series[R, V] = {
164+
var d = data match {
165+
case d: DenseMatrix[V] => d.apply(ri, ::)
166+
case d: SliceMatrix[Int, Int, V] => d.apply(ri, ::)
167+
case _ => ???
168+
}
169+
Series(rowIdx, d.t)
170+
}
171+
172+
def get(c: C): Series[R, V] = {
173+
var i = colIdx.hashIndexOfUnsafe(c)
174+
iget(i)
175+
}
147176
}
148177

149178
def withIdx[R, C](rows: IndexVector[R], cols: IndexVector[C])
@@ -298,7 +327,17 @@ object DataFrame {
298327
DenseMatrix.fill(ridx.size, cidx.size)(fillValue)
299328
)
300329

301-
def fromSeries[R:ClassTag,C:ClassTag:Ordering,V:ClassTag:Semiring](columns: (C, Series[R,V])*) : DataFrame[R, C, V] = {
330+
def fromSeriesColumns[R:ClassTag,C:ClassTag:Ordering,V:ClassTag:Semiring](columns: (C, Series[R,V])*)
331+
: DataFrame[R, C, V] = fromSeriesColumns(columns.toIndexedSeq)
332+
333+
def fromSeriesColumns[R:ClassTag,C:ClassTag:Ordering,V:ClassTag:Semiring](columns: Iterable[(C, Series[R,V])])
334+
: DataFrame[R, C, V] = fromSeriesColumns(columns.toIndexedSeq)
335+
336+
def fromSeriesColumns[R:ClassTag,C:ClassTag:Ordering,V:ClassTag:Semiring](columns: IterableOnce[(C, Series[R,V])])
337+
: DataFrame[R, C, V] = fromSeriesColumns(columns.iterator.toIndexedSeq)
338+
339+
def fromSeriesColumns[R:ClassTag,C:ClassTag:Ordering,V:ClassTag:Semiring](columns: IndexedSeq[(C, Series[R,V])])
340+
: DataFrame[R, C, V] = {
302341
var columnIdx = DataIndexVector(columns.map(i=>i._1))
303342
val firstSeries: Series[R,V] = columns(0)._2
304343
var df : DataFrame[R, C, V] = fill(firstSeries.idx, columnIdx, firstSeries.data(0))

src/main/scala/qnt/bz/IndexVector.scala

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -142,7 +142,7 @@ abstract class IndexVector[V] () (implicit val ord: Ordering[V], val tag: ClassT
142142
val startIdx = indexOfBinarySearch(start)
143143
val endIdx = indexOfBinarySearch(end)
144144
if(startIdx.notFound || endIdx.notFound) {
145-
IndexVector.empty[V].iloc()
145+
IndexVector.empty[V].iloc(Seq())
146146
} else {
147147
ilocRange(
148148
if(step > 0)

src/main/scala/qnt/bz/Series.scala

Lines changed: 40 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -9,8 +9,7 @@ import scala.reflect.ClassTag
99
class Series[I, @specialized(Double, Int, Float, Long) V]
1010
(val idx: IndexVector[I], val data: Vector[V])(implicit iTag:ClassTag[I], vTag: ClassTag[V], vSem: Semiring[V])
1111
extends scala.collection.Map[I, V]
12-
with Slice1dOps[I, Series[I, V]]
13-
{
12+
with Slice1dOps[I, Series[I, V]] {
1413

1514
if (idx.size != data.length) {
1615
throw new IllegalArgumentException("index.length != values.length")
@@ -46,29 +45,29 @@ class Series[I, @specialized(Double, Int, Float, Long) V]
4645

4746
override def toString: String = toString(5, 5)
4847

49-
def toString(head: Int, tail:Int, indexFormat:I=>String = _.toString, dataFormat: V=>String = _.toString): String = {
50-
val rows = Math.min(idx.size, head+tail+1)
51-
val output = Array.ofDim[String](rows+2, 2)
48+
def toString(head: Int, tail: Int, indexFormat: I => String = _.toString, dataFormat: V => String = _.toString): String = {
49+
val rows = Math.min(idx.size, head + tail + 1)
50+
val output = Array.ofDim[String](rows + 2, 2)
5251
output(0)(0) = s"Series[${iTag.runtimeClass.getSimpleName},${vTag.runtimeClass.getSimpleName}]:"
5352
output(0)(1) = ""
5453
output(1)(0) = s"index"
5554
output(1)(1) = s"value"
56-
for(i <- 0 until rows) {
55+
for (i <- 0 until rows) {
5756
val j = if (i < head) i else (idx.size - rows + i)
58-
output(2+i)(0) = indexFormat(idx(j))
59-
output(2+i)(1) = dataFormat(data(j))
57+
output(2 + i)(0) = indexFormat(idx(j))
58+
output(2 + i)(1) = dataFormat(data(j))
6059
if (rows < idx.size && i == head) {
61-
output(2+i)(0) = "..."
62-
output(2+i)(1) = "..."
60+
output(2 + i)(0) = "..."
61+
output(2 + i)(1) = "..."
6362
}
6463
}
6564
// adjust column size
66-
for(c <- 0 to 1) {
65+
for (c <- 0 to 1) {
6766
var size = 0
68-
for(r <- 1 until output.length) {
67+
for (r <- 1 until output.length) {
6968
size = Math.max(size, output(r)(c).length)
7069
}
71-
for(r <- 1 until output.length) {
70+
for (r <- 1 until output.length) {
7271
output(r)(c) = output(r)(c) + " " * (size - output(r)(c).length)
7372
}
7473
}
@@ -95,23 +94,23 @@ class Series[I, @specialized(Double, Int, Float, Long) V]
9594
this.align(idx)
9695
}
9796

98-
def align(idx: IndexVector[I]): Series[I,V] = {
97+
def align(idx: IndexVector[I]): Series[I, V] = {
9998
val result = {
100-
if(this.idx == idx) this
101-
else if (idx.forall(i => this.idx.contains(i))) Series[I,V](idx, this.data(this.idx.loc(idx.toIndexedSeq).slices))
99+
if (this.idx == idx) this
100+
else if (idx.forall(i => this.idx.contains(i))) Series[I, V](idx, this.data(this.idx.loc(idx.toIndexedSeq).slices))
102101
else {
103102
var r = Series(idx, new DenseVector[V](idx.size))
104103
var ii = idx.intersect(this.idx)
105-
for(k <- ii.toIndexedSeq) {
106-
r(k) = this(k)
104+
for (k <- ii.toIndexedSeq) {
105+
r(k) = this (k)
107106
}
108107
r
109108
}
110109
}
111110
result
112111
}
113112

114-
def fillLike(fillValue:V): Series[I, V] = Series.fill(idx, fillValue)
113+
def fillLike(fillValue: V): Series[I, V] = Series.fill(idx, fillValue)
115114

116115
override def get(key: I): Option[V] = idx.hashIndexOf(key).map(i => data(i))
117116

@@ -120,6 +119,28 @@ class Series[I, @specialized(Double, Int, Float, Long) V]
120119
override def -(key: I): collection.Map[I, V] = ???
121120

122121
override def -(key1: I, key2: I, keys: I*): collection.Map[I, V] = ???
122+
123+
def shift(period:Int, fillValue: V): Series[I, V] = {
124+
val result = copy
125+
if(period > 0) {
126+
for(i <- idx.indices) {
127+
if(i < period) {
128+
result.data.update(i, fillValue)
129+
} else {
130+
result.data.update(i, this.data(i - period))
131+
}
132+
}
133+
} else if (period < 0) {
134+
for(i <- idx.indices) {
135+
if(i > idx.indices.last - period) {
136+
result.data.update(i, fillValue)
137+
} else {
138+
result.data.update(i, this.data(i + period))
139+
}
140+
}
141+
}
142+
result
143+
}
123144
}
124145

125146
object Series {

src/main/scala/qnt/bz/Slice1dOps.scala

Lines changed: 3 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -4,23 +4,21 @@ trait Slice1dOps[K, S] {
44
def size: Int
55

66
def iloc(vals: Int*): S = iloc(vals.toIndexedSeq)
7-
def iloc(vals: Iterable[Int]): S = iloc(vals.toIndexedSeq)
87
def iloc(vals: IterableOnce[Int]): S = iloc(vals.iterator.toIndexedSeq)
8+
def iloc(vals: Iterable[Int]): S = iloc(vals.toIndexedSeq)
99
def iloc(vals: IndexedSeq[Int]): S
1010
def ilocRange(start: Int, end: Int, step: Int = 1, keepStart: Boolean = true, keepEnd: Boolean = true, round: Boolean = true)
1111
: S = iloc(RoundArrayRange(size, start, end, step, keepStart, keepEnd, round))
1212

1313
def mask(m: Boolean*): S = mask(m.toIndexedSeq)
14-
def mask(m: Iterable[Boolean]): S = mask(m.toIndexedSeq)
15-
def mask(m: IterableOnce[Boolean]): S = mask(m.iterator.toIndexedSeq)
16-
def mask(m: IndexedSeq[Boolean]): S = {
14+
def mask(m: IterableOnce[Boolean]): S = {
1715
val idx = m.iterator.zipWithIndex.filter(_._1).map(_._2).toArray
1816
iloc(idx)
1917
}
2018

2119
def loc(vals: K*):S = loc(vals.toIndexedSeq)
22-
def loc(vals: Iterable[K]): S = loc(vals.toIndexedSeq)
2320
def loc(vals: IterableOnce[K]): S = loc(vals.iterator.toIndexedSeq)
21+
def loc(vals: Iterable[K]): S = loc(vals.iterator.toIndexedSeq)
2422
def loc(vals: IndexedSeq[K]): S
2523
def locRange(start: K, end: K, step: Int = 1, keepStart: Boolean = true, keepEnd: Boolean = true, round: Boolean = true): S
2624
}

0 commit comments

Comments
 (0)