daru 0.1.0 → 0.1.1

Sign up to get free protection for your applications and to get access to all the features.
Files changed (55) hide show
  1. checksums.yaml +4 -4
  2. data/.build.sh +6 -6
  3. data/.gitignore +2 -0
  4. data/CONTRIBUTING.md +7 -3
  5. data/History.md +36 -0
  6. data/README.md +21 -13
  7. data/Rakefile +16 -1
  8. data/benchmarks/TradeoffData.csv +65 -0
  9. data/benchmarks/dataframe_creation.rb +39 -0
  10. data/benchmarks/group_by.rb +32 -0
  11. data/benchmarks/row_access.rb +41 -0
  12. data/benchmarks/row_assign.rb +36 -0
  13. data/benchmarks/sorting.rb +44 -0
  14. data/benchmarks/vector_access.rb +31 -0
  15. data/benchmarks/vector_assign.rb +42 -0
  16. data/benchmarks/where_clause.rb +48 -0
  17. data/benchmarks/where_vs_filter.rb +28 -0
  18. data/daru.gemspec +29 -5
  19. data/lib/daru.rb +30 -1
  20. data/lib/daru/accessors/array_wrapper.rb +2 -2
  21. data/lib/daru/accessors/nmatrix_wrapper.rb +6 -6
  22. data/lib/daru/core/group_by.rb +112 -31
  23. data/lib/daru/core/merge.rb +170 -0
  24. data/lib/daru/core/query.rb +95 -0
  25. data/lib/daru/dataframe.rb +335 -223
  26. data/lib/daru/date_time/index.rb +550 -0
  27. data/lib/daru/date_time/offsets.rb +397 -0
  28. data/lib/daru/index.rb +266 -54
  29. data/lib/daru/io/io.rb +1 -2
  30. data/lib/daru/maths/arithmetic/dataframe.rb +2 -2
  31. data/lib/daru/maths/arithmetic/vector.rb +2 -2
  32. data/lib/daru/maths/statistics/dataframe.rb +58 -8
  33. data/lib/daru/maths/statistics/vector.rb +229 -0
  34. data/lib/daru/vector.rb +230 -80
  35. data/lib/daru/version.rb +1 -1
  36. data/spec/core/group_by_spec.rb +16 -16
  37. data/spec/core/merge_spec.rb +52 -0
  38. data/spec/core/query_spec.rb +171 -0
  39. data/spec/dataframe_spec.rb +278 -280
  40. data/spec/date_time/data_spec.rb +199 -0
  41. data/spec/date_time/index_spec.rb +433 -0
  42. data/spec/date_time/offsets_spec.rb +371 -0
  43. data/spec/fixtures/stock_data.csv +500 -0
  44. data/spec/index_spec.rb +317 -11
  45. data/spec/io/io_spec.rb +18 -17
  46. data/spec/math/arithmetic/dataframe_spec.rb +3 -3
  47. data/spec/math/statistics/dataframe_spec.rb +39 -1
  48. data/spec/math/statistics/vector_spec.rb +163 -1
  49. data/spec/monkeys_spec.rb +4 -0
  50. data/spec/spec_helper.rb +3 -0
  51. data/spec/vector_spec.rb +125 -60
  52. metadata +71 -14
  53. data/lib/daru/accessors/dataframe_by_vector.rb +0 -17
  54. data/lib/daru/multi_index.rb +0 -216
  55. data/spec/multi_index_spec.rb +0 -216
@@ -49,7 +49,15 @@ describe Daru::DataFrame do
49
49
  end
50
50
 
51
51
  context "#max" do
52
- # TODO
52
+ it "returns the row that has max" do
53
+ df = Daru::DataFrame.new({
54
+ a: [1,2,3,4,5],
55
+ b: ['aa','aaa','a','','dfffdf'],
56
+ c: [11,22,33,44,55]
57
+ })
58
+ expect(df.max(vector: :b)).to eq(
59
+ Daru::Vector.new([5,'dfffdf',55], index: [:a, :b, :c]))
60
+ end
53
61
  end
54
62
 
55
63
  context "#min" do
@@ -107,4 +115,34 @@ describe Daru::DataFrame do
107
115
  ))
108
116
  end
109
117
  end
118
+
119
+ context "#cumsum" do
120
+ it "calculates cumulative sum of numeric vectors" do
121
+ answer = Daru::DataFrame.new({
122
+ d: [1,3,5,8,11,15,20,26,33],
123
+ e: [2,6,10,16,22,30,40,52,66],
124
+ f: [10,30,50,80,110,150,200,260,330]
125
+ })
126
+ expect(@df.cumsum).to eq(answer)
127
+ end
128
+ end
129
+
130
+ context "#rolling_mean" do
131
+ it "calculates rolling mean" do
132
+ v = Daru::Vector.new([17.28, 17.45, 17.84, 17.74, 17.82, 17.85, 17.36, 17.3, 17.56, 17.49, 17.46, 17.4, 17.03, 17.01,16.86, 16.86, 16.56, 16.36, 16.66, 16.77])
133
+ df = Daru::DataFrame.new({ a: v, b: v, c: v })
134
+ answer = df.rolling_mean
135
+
136
+ expect(answer[:a][-1]) .to be_within(0.001).of(16.897)
137
+ expect(answer[:b][-5]) .to be_within(0.001).of(17.233)
138
+ expect(answer[:c][-10]).to be_within(0.001).of(17.587)
139
+ end
140
+ end
141
+
142
+ context "#standardize" do
143
+ it "standardizes" do
144
+ # TODO: Write this test.
145
+ @df.standardize
146
+ end
147
+ end
110
148
  end
@@ -111,6 +111,16 @@ describe Daru::Vector do
111
111
  end
112
112
  end
113
113
 
114
+ context "#value_counts" do
115
+ it "counts number of unique values in the Vector" do
116
+ vector = Daru::Vector.new(
117
+ ["America","America","America","America","America",
118
+ "India","India", "China", "India", "China"])
119
+ expect(vector.value_counts).to eq(
120
+ Daru::Vector.new([5,3,2], index: ["America", "India", "China"]))
121
+ end
122
+ end
123
+
114
124
  context "#coefficient_of_variation" do
115
125
  it "calculates coefficient_of_variation" do
116
126
  @dv.coefficient_of_variation
@@ -344,4 +354,156 @@ describe Daru::Vector do
344
354
  expect_correct_vector_in_delta(exp, ds[:mean], 1e-13)
345
355
  end
346
356
  end
347
- end
357
+
358
+ before do
359
+ # daily closes of iShares XIU on the TSX
360
+ @shares = Daru::Vector.new([17.28, 17.45, 17.84, 17.74, 17.82, 17.85, 17.36, 17.3, 17.56, 17.49, 17.46, 17.4, 17.03, 17.01,16.86, 16.86, 16.56, 16.36, 16.66, 16.77])
361
+ end
362
+
363
+ context "#acf" do
364
+ it "calculates autocorrelation co-efficients" do
365
+ acf = @shares.acf
366
+
367
+ expect(acf.length).to eq(14)
368
+
369
+ # test the first few autocorrelations
370
+ expect(acf[0]).to be_within(0.0001).of(1.0)
371
+ expect(acf[1]).to be_within(0.001) .of(0.852)
372
+ expect(acf[2]).to be_within(0.001) .of(0.669)
373
+ expect(acf[3]).to be_within(0.001) .of(0.486)
374
+ end
375
+ end
376
+
377
+ context "#diff" do
378
+ it "performs the difference of the series" do
379
+ diff = @shares.diff
380
+
381
+ expect(diff.class).to eq(Daru::Vector)
382
+ expect(diff[@shares.size - 1]).to be_within(0.001).of( 0.11)
383
+ expect(diff[@shares.size - 2]).to be_within(0.001).of( 0.30)
384
+ expect(diff[@shares.size - 3]).to be_within(0.001).of(-0.20)
385
+ end
386
+ end
387
+
388
+ context "#rolling" do
389
+ it "calculates rolling mean" do
390
+ ma10 = @shares.rolling_mean
391
+
392
+ expect(ma10[-1]) .to be_within(0.001).of(16.897)
393
+ expect(ma10[-5]) .to be_within(0.001).of(17.233)
394
+ expect(ma10[-10]).to be_within(0.001).of(17.587)
395
+
396
+ # test with a different lookback period
397
+ ma5 = @shares.rolling :mean, 5
398
+
399
+ expect(ma5[-1]).to be_within(0.001).of(16.642)
400
+ expect(ma5[-10]).to be_within(0.001).of(17.434)
401
+ expect(ma5[-15]).to be_within(0.001).of(17.74)
402
+ end
403
+
404
+ it "calculates rolling median" do
405
+ me10 = @shares.rolling_median.round(2)
406
+ expect(me10).to eq(Daru::Vector.new([nil,nil,nil,nil,nil,nil,nil,nil,nil,17.525,17.525,17.525,17.475,17.430,17.380,17.330,17.165,17.020,16.94,16.860]).round(2))
407
+
408
+ me5 = @shares.rolling(:median, 5).round(2)
409
+ expect(me5).to eq(Daru::Vector.new([nil,nil,nil,nil,17.74,17.82,17.82,17.74,17.56,17.49,17.46,17.46,17.46,17.40,17.03,17.01,16.86,16.86,16.66,16.66]))
410
+ end
411
+
412
+ it "calculates rolling max" do
413
+ max10 = @shares.rolling_max.round(2)
414
+ expect(max10).to eq(Daru::Vector.new([nil,nil,nil,nil,nil,nil,nil,nil,nil,17.85,17.85,17.85,17.85,17.85,17.85,17.56,17.56,17.56,17.49,17.46]))
415
+
416
+ max5 = @shares.rolling(:max, 5).round(2)
417
+ expect(max5).to eq(Daru::Vector.new([nil, nil, nil, nil,17.84,17.85,17.85,17.85,17.85,17.85,17.56,17.56,17.56,17.49,17.46,17.40,17.03,17.01,16.86,16.86]))
418
+ end
419
+
420
+ it "calculates rolling min" do
421
+ min10 = @shares.rolling_min.round(2)
422
+ expect(min10).to eq(Daru::Vector.new([nil,nil,nil,nil,nil,nil,nil,nil,nil,17.28,17.30,17.30,17.03,17.01,16.86,16.86,16.56,16.36,16.36,16.36]))
423
+
424
+ min5 = @shares.rolling(:min, 5).round(2)
425
+ expect(min5).to eq(Daru::Vector.new([nil,nil,nil,nil,17.28,17.45,17.36,17.30,17.30,17.30,17.30,17.30,17.03,17.01,16.86,16.86,16.56,16.36,16.36,16.36]))
426
+ end
427
+
428
+ it "calculates rolling sum" do
429
+ sum10 = @shares.rolling_sum.round(2)
430
+ expect(sum10).to eq(Daru::Vector.new([nil,nil,nil,nil,nil,nil,nil,nil,nil,175.69,175.87,175.82,175.01,174.28,173.32,172.33,171.53,170.59,169.69,168.97]))
431
+
432
+ sum5 = @shares.rolling(:sum, 5).round(2)
433
+ expect(sum5).to eq(Daru::Vector.new([nil,nil,nil,nil,88.13,88.70,88.61,88.07,87.89,87.56,87.17,87.21,86.94,86.39,85.76,85.16,84.32,83.65,83.30,83.21]))
434
+ end
435
+
436
+ it "calculates rolling std" do
437
+ std10 = @shares.rolling_std.round(2)
438
+ expect(std10).to eq(Daru::Vector.new([nil,nil,nil,nil,nil,nil,nil,nil,nil,0.227227,0.208116,0.212331,0.253485,0.280666,0.295477,0.267127,0.335826,0.412834,0.388886,0.345995]).round(2))
439
+
440
+ std5 = @shares.rolling(:std, 5).round(2)
441
+ expect(std5).to eq(Daru::Vector.new([nil,nil,nil,nil,0.248556,0.167780,0.206930,0.263211,0.253811,0.215105,0.103827,0.098082,0.208255,0.237844,0.263002,0.220839,0.187963,0.263629,0.212132,0.193959]).round(2))
442
+ end
443
+
444
+ it "calculates rolling variance" do
445
+ var10 = @shares.rolling_variance.round(2)
446
+ expect(var10).to eq(Daru::Vector.new([nil,nil,nil,nil,nil,nil,nil,nil,nil,0.051632,0.043312,0.045084,0.064254,0.078773,0.087307,0.071357,0.112779,0.170432,0.151232,0.119712]).round(2))
447
+
448
+ var5 = @shares.rolling(:variance, 5).round(2)
449
+ expect(var5).to eq(Daru::Vector.new([nil,nil,nil,nil,0.06178,0.02815,0.04282,0.06928,0.06442,0.04627,0.01078,0.00962,0.04337,0.05657,0.06917,0.04877,0.03533,0.06950,0.04500,0.03762]).round(2))
450
+ end
451
+
452
+ it "calculates rolling non-nil count" do
453
+ @shares.rolling_count
454
+ end
455
+ end
456
+
457
+ context "#ema" do
458
+ it "calculates exponential moving average" do
459
+ # test default
460
+ ema10 = @shares.ema
461
+
462
+ expect(ema10[-1]) .to be_within(0.00001).of( 16.87187)
463
+ expect(ema10[-5]) .to be_within(0.00001).of( 17.19187)
464
+ expect(ema10[-10]).to be_within(0.00001).of( 17.54918)
465
+
466
+ # test with a different lookback period
467
+ ema5 = @shares.ema 5
468
+
469
+ expect(ema5[-1]) .to be_within( 0.0001).of(16.71299)
470
+ expect(ema5[-10]).to be_within( 0.0001).of(17.49079)
471
+ expect(ema5[-15]).to be_within( 0.0001).of(17.70067)
472
+
473
+ # test with a different smoother
474
+ ema_w = @shares.ema 10, true
475
+
476
+ expect(ema_w[-1]) .to be_within(0.00001).of(17.08044)
477
+ expect(ema_w[-5]) .to be_within(0.00001).of(17.33219)
478
+ expect(ema_w[-10]).to be_within(0.00001).of(17.55810)
479
+ end
480
+ end
481
+
482
+ context "#macd" do
483
+ it "calculates moving average convergence divergence" do
484
+ # MACD uses a lot more data than the other ones, so we need a bigger vector
485
+ data = Daru::Vector.new(
486
+ File.readlines("spec/fixtures/stock_data.csv").map(&:to_f))
487
+
488
+ macd, signal = data.macd
489
+
490
+ # check the MACD
491
+ expect(macd[-1]).to be_within(1e-6).of(3.12e-4)
492
+ expect(macd[-10]).to be_within(1e-4).of(-1.07e-2)
493
+ expect(macd[-20]).to be_within(1e-5).of(-5.65e-3)
494
+
495
+ # check the signal
496
+ expect(signal[-1]).to be_within(1e-5).of(-0.00628)
497
+ expect(signal[-10]).to be_within(1e-5).of(-0.00971)
498
+ expect(signal[-20]).to be_within(1e-5).of(-0.00338)
499
+ end
500
+ end
501
+
502
+ context "#cumsum" do
503
+ it "calculates cumulative sum" do
504
+ vector = Daru::Vector.new([1,2,3,4,5,6,7,8,9,10])
505
+ expect(vector.cumsum).to eq(
506
+ Daru::Vector.new([1,3,6,10,15,21,28,36,45,55]))
507
+ end
508
+ end
509
+ end
@@ -2,6 +2,10 @@ require 'spec_helper.rb'
2
2
 
3
3
  describe "Monkeys" do
4
4
  context Array do
5
+ it "#recode_repeated" do
6
+ expect([1,1,'a','a','b',:c,2].recode_repeated).to eq(
7
+ ['1_1', '1_2','a_1','a_2','b',:c,2])
8
+ end
5
9
  end
6
10
 
7
11
  context Matrix do
@@ -3,6 +3,7 @@ require 'matrix'
3
3
  require 'awesome_print'
4
4
  require 'distribution'
5
5
  require 'tempfile'
6
+ require 'pry-byebug'
6
7
 
7
8
  def mri?
8
9
  RUBY_ENGINE == 'ruby'
@@ -18,6 +19,8 @@ else
18
19
  require 'nmatrix'
19
20
  end
20
21
 
22
+ RSpec::Expectations.configuration.warn_about_potential_false_positives = false
23
+
21
24
 
22
25
  $LOAD_PATH.unshift(File.join(File.dirname(__FILE__), '..', 'lib'))
23
26
  $LOAD_PATH.unshift(File.dirname(__FILE__))
@@ -18,7 +18,7 @@ describe Daru::Vector do
18
18
  [:b, :two, :baz]
19
19
  ]
20
20
 
21
- @multi_index = Daru::MultiIndex.new(@tuples)
21
+ @multi_index = Daru::MultiIndex.from_tuples(@tuples)
22
22
  end
23
23
 
24
24
  it "initializes from an Array" do
@@ -77,6 +77,12 @@ describe Daru::Vector do
77
77
  dv = Daru::Vector.new [1,2], name: :mi, index: @multi_index, dtype: :array
78
78
  expect(dv).to eq(Daru::Vector.new([1,2,nil,nil], name: :mi, index: @multi_index, dtype: :array))
79
79
  end
80
+
81
+ it "accepts all sorts of objects for indexing" do
82
+ dv = Daru::Vector.new [1,2,3,4], index: ['a', 'b', :r, 0]
83
+ expect(dv.to_a).to eq([1,2,3,4])
84
+ expect(dv.index.to_a).to eq(['a', 'b', :r, 0])
85
+ end
80
86
  end
81
87
 
82
88
  context ".new_with_size" do
@@ -147,6 +153,14 @@ describe Daru::Vector do
147
153
  expect(@dv[3..4]).to eq(Daru::Vector.new([4,5], name: :yoga,
148
154
  index: [:padme, :r2d2], dtype: dtype))
149
155
  end
156
+
157
+ it "returns correct results for index of multiple index" do
158
+ v = Daru::Vector.new([1,2,3,4], index: ['a','c',1,:a])
159
+ expect(v['a']).to eq(1)
160
+ expect(v[:a]).to eq(4)
161
+ expect(v[1]).to eq(3)
162
+ expect(v[0]).to eq(1)
163
+ end
150
164
  end
151
165
 
152
166
  context Daru::MultiIndex do
@@ -165,9 +179,10 @@ describe Daru::Vector do
165
179
  [:c,:two,:foo],
166
180
  [:c,:two,:bar]
167
181
  ]
168
- @multi_index = Daru::MultiIndex.new(@tuples)
169
- @vector = Daru::Vector.new Array.new(12) { |i| i }, index: @multi_index,
170
- dtype: dtype, name: :mi_vector
182
+ @multi_index = Daru::MultiIndex.from_tuples(@tuples)
183
+ @vector = Daru::Vector.new(
184
+ Array.new(12) { |i| i }, index: @multi_index,
185
+ dtype: dtype, name: :mi_vector)
171
186
  end
172
187
 
173
188
  it "returns a single element when passed a row number" do
@@ -179,7 +194,7 @@ describe Daru::Vector do
179
194
  end
180
195
 
181
196
  it "returns sub vector when passed first layer of tuple" do
182
- mi = Daru::MultiIndex.new([
197
+ mi = Daru::MultiIndex.from_tuples([
183
198
  [:one,:bar],
184
199
  [:one,:baz],
185
200
  [:two,:bar],
@@ -189,7 +204,7 @@ describe Daru::Vector do
189
204
  end
190
205
 
191
206
  it "returns sub vector when passed first and second layer of tuple" do
192
- mi = Daru::MultiIndex.new([
207
+ mi = Daru::MultiIndex.from_tuples([
193
208
  [:foo],
194
209
  [:bar]])
195
210
  expect(@vector[:c,:two]).to eq(Daru::Vector.new([10,11], index: mi,
@@ -197,7 +212,7 @@ describe Daru::Vector do
197
212
  end
198
213
 
199
214
  it "returns a vector with corresponding MultiIndex when specified numeric Range" do
200
- mi = Daru::MultiIndex.new([
215
+ mi = Daru::MultiIndex.from_tuples([
201
216
  [:a,:two,:baz],
202
217
  [:b,:one,:bar],
203
218
  [:b,:two,:bar],
@@ -233,6 +248,21 @@ describe Daru::Vector do
233
248
  @dv[0] = nil
234
249
  expect(@dv.dtype).to eq(:array)
235
250
  end
251
+
252
+ it "assigns correctly for a mixed index Vector" do
253
+ v = Daru::Vector.new [1,2,3,4], index: ['a',:a,0,66]
254
+ v['a'] = 666
255
+ expect(v['a']).to eq(666)
256
+
257
+ v[0] = 666
258
+ expect(v[0]).to eq(666)
259
+
260
+ v[3] = 666
261
+ expect(v[3]).to eq(666)
262
+
263
+ expect(v).to eq(Daru::Vector.new([666,2,666,666],
264
+ index: ['a',:a,0,66]))
265
+ end
236
266
  end
237
267
 
238
268
  context Daru::MultiIndex do
@@ -251,7 +281,7 @@ describe Daru::Vector do
251
281
  [:c,:two,:foo],
252
282
  [:c,:two,:bar]
253
283
  ]
254
- @multi_index = Daru::MultiIndex.new(@tuples)
284
+ @multi_index = Daru::MultiIndex.from_tuples(@tuples)
255
285
  @vector = Daru::Vector.new Array.new(12) { |i| i }, index: @multi_index,
256
286
  dtype: dtype, name: :mi_vector
257
287
  end
@@ -293,21 +323,12 @@ describe Daru::Vector do
293
323
  @dv.concat 6, :ibanez
294
324
 
295
325
  expect(@dv.index) .to eq(
296
- [:warwick, :thompson, :jackson, :fender, :esp, :ibanez].to_index)
326
+ Daru::Index.new([:warwick, :thompson, :jackson, :fender, :esp, :ibanez]))
297
327
  expect(@dv[:ibanez]).to eq(6)
298
328
  expect(@dv[5]) .to eq(6)
299
329
  end
300
330
 
301
- it "concatenates without index if index is default numeric" do
302
- vector = Daru::Vector.new [1,2,3,4,5], name: :nums, dtype: dtype
303
-
304
- vector.concat 6
305
-
306
- expect(vector.index).to eq([0,1,2,3,4,5].to_index)
307
- expect(vector[5]) .to eq(6)
308
- end
309
-
310
- it "raises error if index not specified and non-numeric index" do
331
+ it "raises error if index not specified" do
311
332
  expect {
312
333
  @dv.concat 6
313
334
  }.to raise_error
@@ -320,13 +341,10 @@ describe Daru::Vector do
320
341
  dv = Daru::Vector.new [1,2,3,4,5], name: :a, dtype: dtype
321
342
 
322
343
  dv.delete 3
323
- expect(dv).to eq(Daru::Vector.new [1,2,4,5], name: :a)
344
+ expect(dv).to eq(
345
+ Daru::Vector.new [1,2,4,5], name: :a, index: [0,1,3,4])
324
346
  end
325
347
  end
326
-
327
- context Daru::MultiIndex do
328
- pending
329
- end
330
348
  end
331
349
 
332
350
  context "#delete_at" do
@@ -344,22 +362,19 @@ describe Daru::Vector do
344
362
  end
345
363
 
346
364
  it "deletes element of specified integer index" do
365
+ pending
347
366
  @dv.delete_at 2
348
367
 
349
368
  expect(@dv).to eq(Daru::Vector.new [1,2,4,5], name: :a,
350
369
  index: [:one, :two, :four, :five], dtype: dtype)
351
370
  end
352
371
  end
353
-
354
- context Daru::MultiIndex do
355
- pending "Possibly next release"
356
- end
357
372
  end
358
373
 
359
374
  context "#delete_if" do
360
375
  it "deletes elements if block evaluates to true" do
361
376
  v = Daru::Vector.new [1,22,33,45,65,32,524,656,123,99,77], dtype: dtype
362
- ret = v.delete_if { |d| d % 11 != 0 }
377
+ ret = v.delete_if { |d| d % 11 == 0 }
363
378
  expect(ret).to eq(
364
379
  Daru::Vector.new([1,45,65,32,524,656,123],
365
380
  index: [0,3,4,5,6,7,8], dtype: dtype))
@@ -367,6 +382,17 @@ describe Daru::Vector do
367
382
  end
368
383
  end
369
384
 
385
+ context "#keep_if" do
386
+ it "keeps elements if block returns true" do
387
+ v = Daru::Vector.new([1,22,33,45,65,32,524,656,123,99,77], dtype: dtype)
388
+ ret = v.keep_if { |d| d < 35 }
389
+
390
+ expect(ret).to eq(
391
+ Daru::Vector.new([1,22,33,32], index: [0,1,2,5], dtype: dtype))
392
+ expect(v.dtype).to eq(ret.dtype)
393
+ end
394
+ end
395
+
370
396
  context "#index_of" do
371
397
  context Daru::Index do
372
398
  it "returns index of specified value" do
@@ -379,7 +405,7 @@ describe Daru::Vector do
379
405
 
380
406
  context Daru::MultiIndex do
381
407
  it "returns tuple of specified value" do
382
- mi = Daru::MultiIndex.new([
408
+ mi = Daru::MultiIndex.from_tuples([
383
409
  [:a,:two,:bar],
384
410
  [:a,:two,:baz],
385
411
  [:b,:one,:bar],
@@ -405,7 +431,7 @@ describe Daru::Vector do
405
431
  pending
406
432
  # it "returns vector as a Hash" do
407
433
  # pending
408
- # mi = Daru::MultiIndex.new([
434
+ # mi = Daru::MultiIndex.from_tuples([
409
435
  # [:a,:two,:bar],
410
436
  # [:a,:two,:baz],
411
437
  # [:b,:one,:bar],
@@ -469,7 +495,7 @@ describe Daru::Vector do
469
495
 
470
496
  context Daru::MultiIndex do
471
497
  before do
472
- mi = Daru::MultiIndex.new([
498
+ mi = Daru::MultiIndex.from_tuples([
473
499
  [:a, :one, :foo],
474
500
  [:a, :two, :bar],
475
501
  [:b, :one, :bar],
@@ -481,7 +507,7 @@ describe Daru::Vector do
481
507
  end
482
508
 
483
509
  it "sorts vector" do
484
- mi_asc = Daru::MultiIndex.new([
510
+ mi_asc = Daru::MultiIndex.from_tuples([
485
511
  [:b, :three, :bar],
486
512
  [:b, :two, :baz],
487
513
  [:a, :two, :bar],
@@ -493,7 +519,7 @@ describe Daru::Vector do
493
519
  end
494
520
 
495
521
  it "sorts in descending" do
496
- mi_dsc = Daru::MultiIndex.new([
522
+ mi_dsc = Daru::MultiIndex.from_tuples([
497
523
  [:b, :one, :bar],
498
524
  [:a, :one, :foo],
499
525
  [:a, :two, :bar],
@@ -505,7 +531,7 @@ describe Daru::Vector do
505
531
  end
506
532
 
507
533
  it "sorts using the supplied block" do
508
- mi_abs = Daru::MultiIndex.new([
534
+ mi_abs = Daru::MultiIndex.from_tuples([
509
535
  [:b, :two, :baz],
510
536
  [:a, :two, :bar],
511
537
  [:a, :one, :foo],
@@ -518,29 +544,33 @@ describe Daru::Vector do
518
544
  end
519
545
  end
520
546
 
521
- context "#reindex" do
522
- context Daru::Index do
523
- before do
524
- @dv = Daru::Vector.new [1,2,3,4,5], name: :dv, index: [:a, :b, :c, :d, :e]
525
- end
526
-
527
- it "recreates index with sequential numbers" do
528
- a = @dv.reindex(:seq)
547
+ context "#index=" do
548
+ before do
549
+ @vector = Daru::Vector.new([1,2,3,4,5])
550
+ end
529
551
 
530
- expect(a).to eq(Daru::Vector.new([1,2,3,4,5], name: :dv, index: [0,1,2,3,4]))
531
- expect(a).to_not eq(@dv)
532
- end
552
+ it "simply reassigns index" do
553
+ index = Daru::DateTimeIndex.date_range(:start => '2012', :periods => 5)
554
+ @vector.index = index
533
555
 
534
- it "accepts a new non-numeric index" do
535
- a = @dv.reindex([:hello, :my, :name, :is, :ted])
556
+ expect(@vector.index.class).to eq(DateTimeIndex)
557
+ expect(@vector['2012-1-1']).to eq(1)
558
+ end
536
559
 
537
- expect(a).to eq(Daru::Vector.new([1,2,3,4,5], name: :dv, index: [:hello, :my, :name, :is, :ted]))
538
- expect(a).to_not eq(@dv)
539
- end
560
+ it "raises error for index size != vector size" do
561
+ expect {
562
+ @vector.index = Daru::Index.new([4,2,6])
563
+ }.to raise_error
540
564
  end
565
+ end
541
566
 
542
- context Daru::MultiIndex do
543
- pending
567
+ context "#reindex" do
568
+ it "intelligently reindexes" do
569
+ vector = Daru::Vector.new([1,2,3,4,5])
570
+ index = Daru::Index.new([3,4,1,0,6])
571
+
572
+ expect(vector.reindex(index)).to eq(
573
+ Daru::Vector.new([4,5,2,1,nil], index: index))
544
574
  end
545
575
  end
546
576
 
@@ -739,7 +769,24 @@ describe Daru::Vector do
739
769
  end
740
770
 
741
771
  context Daru::MultiIndex do
742
- pending
772
+ it "returns indexes of nils" do
773
+ mi = Daru::MultiIndex.from_tuples([
774
+ ['M', 2000],
775
+ ['M', 2001],
776
+ ['M', 2002],
777
+ ['M', 2003],
778
+ ['F', 2000],
779
+ ['F', 2001],
780
+ ['F', 2002],
781
+ ['F', 2003]
782
+ ])
783
+ vector = Daru::Vector.new([nil,2,4,5,3,nil,2,nil], index: mi)
784
+ expect(vector.missing_positions).to eq([
785
+ ['M',2000],
786
+ ['F',2001],
787
+ ['F',2003]
788
+ ])
789
+ end
743
790
  end
744
791
  end
745
792
 
@@ -757,9 +804,9 @@ describe Daru::Vector do
757
804
 
758
805
  context "#type" do
759
806
  before(:each) do
760
- @numeric = Daru::Vector.new([1,2,3,4,5])
761
- @multi = Daru::Vector.new([1,2,3,'sameer','d'])
762
- @with_nils = Daru::Vector.new([1,2,3,4,nil])
807
+ @numeric = Daru::Vector.new([1,2,3,4,5])
808
+ @multi = Daru::Vector.new([1,2,3,'sameer','d'])
809
+ @with_nils = Daru::Vector.new([1,2,3,4,nil])
763
810
  end
764
811
 
765
812
  it "checks numeric data correctly" do
@@ -922,7 +969,7 @@ describe Daru::Vector do
922
969
 
923
970
  it "stores name as a symbol" do
924
971
  @v.rename "This is a vector"
925
- expect(@v.name).to eq(:"This is a vector")
972
+ expect(@v.name).to eq("This is a vector")
926
973
  end
927
974
  end
928
975
 
@@ -966,11 +1013,29 @@ describe Daru::Vector do
966
1013
 
967
1014
  context "#detach_index" do
968
1015
  it "creates a DataFrame with first Vector as index and second as values of the Vector" do
969
- v = Daru::Vector.new([1,2,3,4,5,6], index: [:a, :b, :c, :d, :e, :f], name: :values)
1016
+ v = Daru::Vector.new([1,2,3,4,5,6],
1017
+ index: ['a', 'b', 'c', 'd', 'e', 'f'], name: :values)
970
1018
  expect(v.detach_index).to eq(Daru::DataFrame.new({
971
1019
  index: ['a', 'b', 'c', 'd', 'e', 'f'],
972
- vector: [1,2,3,4,5,6]
1020
+ values: [1,2,3,4,5,6]
973
1021
  }))
974
1022
  end
975
1023
  end
1024
+
1025
+ context "#lag" do
1026
+ it "lags the vector by specified amount" do
1027
+ xiu = Daru::Vector.new([17.28, 17.45, 17.84, 17.74, 17.82, 17.85, 17.36, 17.3, 17.56, 17.49, 17.46, 17.4, 17.03, 17.01,
1028
+ 16.86, 16.86, 16.56, 16.36, 16.66, 16.77])
1029
+ lag1 = xiu.lag
1030
+
1031
+ expect(lag1[lag1.size - 1]).to be_within(0.001).of(16.66)
1032
+ expect(lag1[lag1.size - 2]).to be_within(0.001).of(16.36)
1033
+
1034
+ #test with different lagging unit
1035
+ lag2 = xiu.lag(2)
1036
+
1037
+ expect(lag2[lag2.size - 1]).to be_within(0.001).of(16.36)
1038
+ expect(lag2[lag2.size - 2]).to be_within(0.001).of(16.56)
1039
+ end
1040
+ end
976
1041
  end if mri?