daru 0.1.3.1 → 0.1.4

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (92) hide show
  1. checksums.yaml +4 -4
  2. data/.gitignore +2 -0
  3. data/.rspec +2 -1
  4. data/.rspec_formatter.rb +33 -0
  5. data/.rubocop.yml +26 -2
  6. data/History.md +38 -0
  7. data/README.md +22 -13
  8. data/Rakefile +50 -2
  9. data/benchmarks/csv_reading.rb +22 -0
  10. data/daru.gemspec +9 -2
  11. data/lib/daru.rb +36 -4
  12. data/lib/daru/accessors/array_wrapper.rb +6 -1
  13. data/lib/daru/accessors/dataframe_by_row.rb +10 -2
  14. data/lib/daru/accessors/gsl_wrapper.rb +1 -3
  15. data/lib/daru/accessors/nmatrix_wrapper.rb +9 -0
  16. data/lib/daru/category.rb +935 -0
  17. data/lib/daru/core/group_by.rb +29 -38
  18. data/lib/daru/core/merge.rb +186 -145
  19. data/lib/daru/core/query.rb +22 -11
  20. data/lib/daru/dataframe.rb +976 -885
  21. data/lib/daru/date_time/index.rb +166 -166
  22. data/lib/daru/date_time/offsets.rb +66 -77
  23. data/lib/daru/formatters/table.rb +54 -0
  24. data/lib/daru/helpers/array.rb +40 -0
  25. data/lib/daru/index.rb +476 -73
  26. data/lib/daru/io/io.rb +66 -45
  27. data/lib/daru/io/sql_data_source.rb +33 -62
  28. data/lib/daru/iruby/helpers.rb +38 -0
  29. data/lib/daru/iruby/templates/dataframe.html.erb +52 -0
  30. data/lib/daru/iruby/templates/dataframe_mi.html.erb +58 -0
  31. data/lib/daru/iruby/templates/multi_index.html.erb +12 -0
  32. data/lib/daru/iruby/templates/vector.html.erb +27 -0
  33. data/lib/daru/iruby/templates/vector_mi.html.erb +36 -0
  34. data/lib/daru/maths/arithmetic/dataframe.rb +16 -18
  35. data/lib/daru/maths/arithmetic/vector.rb +4 -6
  36. data/lib/daru/maths/statistics/dataframe.rb +8 -15
  37. data/lib/daru/maths/statistics/vector.rb +120 -98
  38. data/lib/daru/monkeys.rb +12 -40
  39. data/lib/daru/plotting/gruff.rb +3 -0
  40. data/lib/daru/plotting/gruff/category.rb +49 -0
  41. data/lib/daru/plotting/gruff/dataframe.rb +91 -0
  42. data/lib/daru/plotting/gruff/vector.rb +57 -0
  43. data/lib/daru/plotting/nyaplot.rb +3 -0
  44. data/lib/daru/plotting/nyaplot/category.rb +34 -0
  45. data/lib/daru/plotting/nyaplot/dataframe.rb +187 -0
  46. data/lib/daru/plotting/nyaplot/vector.rb +46 -0
  47. data/lib/daru/vector.rb +694 -421
  48. data/lib/daru/version.rb +1 -1
  49. data/profile/_base.rb +23 -0
  50. data/profile/df_to_a.rb +10 -0
  51. data/profile/filter.rb +13 -0
  52. data/profile/joining.rb +13 -0
  53. data/profile/sorting.rb +12 -0
  54. data/profile/vector_each_with_index.rb +9 -0
  55. data/spec/accessors/wrappers_spec.rb +2 -4
  56. data/spec/categorical_spec.rb +1734 -0
  57. data/spec/core/group_by_spec.rb +52 -2
  58. data/spec/core/merge_spec.rb +63 -2
  59. data/spec/core/query_spec.rb +236 -80
  60. data/spec/dataframe_spec.rb +1373 -79
  61. data/spec/date_time/data_spec.rb +3 -5
  62. data/spec/date_time/index_spec.rb +154 -17
  63. data/spec/date_time/offsets_spec.rb +3 -4
  64. data/spec/fixtures/empties.dat +2 -0
  65. data/spec/fixtures/strings.dat +2 -0
  66. data/spec/formatters/table_formatter_spec.rb +99 -0
  67. data/spec/helpers_spec.rb +8 -0
  68. data/spec/index/categorical_index_spec.rb +168 -0
  69. data/spec/index/index_spec.rb +283 -0
  70. data/spec/index/multi_index_spec.rb +570 -0
  71. data/spec/io/io_spec.rb +31 -4
  72. data/spec/io/sql_data_source_spec.rb +0 -1
  73. data/spec/iruby/dataframe_spec.rb +172 -0
  74. data/spec/iruby/helpers_spec.rb +49 -0
  75. data/spec/iruby/multi_index_spec.rb +37 -0
  76. data/spec/iruby/vector_spec.rb +107 -0
  77. data/spec/math/arithmetic/dataframe_spec.rb +71 -13
  78. data/spec/math/arithmetic/vector_spec.rb +8 -10
  79. data/spec/math/statistics/dataframe_spec.rb +3 -5
  80. data/spec/math/statistics/vector_spec.rb +45 -55
  81. data/spec/monkeys_spec.rb +32 -9
  82. data/spec/plotting/dataframe_spec.rb +386 -0
  83. data/spec/plotting/vector_spec.rb +230 -0
  84. data/spec/shared/vector_display_spec.rb +215 -0
  85. data/spec/spec_helper.rb +23 -0
  86. data/spec/vector_spec.rb +905 -138
  87. metadata +143 -11
  88. data/.rubocop_todo.yml +0 -44
  89. data/lib/daru/plotting/dataframe.rb +0 -104
  90. data/lib/daru/plotting/vector.rb +0 -38
  91. data/spec/daru_spec.rb +0 -58
  92. data/spec/index_spec.rb +0 -375
@@ -1,5 +1,3 @@
1
- require 'spec_helper.rb'
2
-
3
1
  describe Daru::Vector do
4
2
  ALL_DTYPES.each do |dtype|
5
3
  describe dtype.to_s do
@@ -84,12 +82,6 @@ describe Daru::Vector do
84
82
  expect(dv.index.to_a).to eq(['a', 'b', :r, 0])
85
83
  end
86
84
 
87
- it "accepts a metadata attribute" do
88
- dv = Daru::Vector.new [1,2,3,4,5], metadata: { cdc_type: 2 }
89
-
90
- expect(dv.metadata) .to eq({ cdc_type: 2 })
91
- end
92
-
93
85
  end
94
86
 
95
87
  context ".new_with_size" do
@@ -129,7 +121,7 @@ describe Daru::Vector do
129
121
  context "#[]" do
130
122
  context Daru::Index do
131
123
  before :each do
132
- @dv = Daru::Vector.new [1,2,3,4,5], name: :yoga, metadata: { cdc_type: 2 },
124
+ @dv = Daru::Vector.new [1,2,3,4,5], name: :yoga,
133
125
  index: [:yoda, :anakin, :obi, :padme, :r2d2], dtype: dtype
134
126
  end
135
127
 
@@ -173,10 +165,6 @@ describe Daru::Vector do
173
165
  expect { @dv[:foo] }.to raise_error(IndexError)
174
166
  expect { @dv[:obi, :foo] }.to raise_error(IndexError)
175
167
  end
176
-
177
- it "retains the original vector metadata" do
178
- expect(@dv[:yoda, :anakin].metadata).to eq({ cdc_type: 2 })
179
- end
180
168
  end
181
169
 
182
170
  context Daru::MultiIndex do
@@ -254,6 +242,266 @@ describe Daru::Vector do
254
242
  expect { @vector[:x, :one] }.to raise_error(IndexError)
255
243
  end
256
244
  end
245
+
246
+ context Daru::CategoricalIndex do
247
+ # before { skip }
248
+ context "non-numerical index" do
249
+ let (:idx) { Daru::CategoricalIndex.new [:a, :b, :a, :a, :c] }
250
+ let (:dv) { Daru::Vector.new 'a'..'e', index: idx }
251
+
252
+ context "single category" do
253
+ context "multiple instances" do
254
+ subject { dv[:a] }
255
+
256
+ it { is_expected.to be_a Daru::Vector }
257
+ its(:size) { is_expected.to eq 3 }
258
+ its(:to_a) { is_expected.to eq ['a', 'c', 'd'] }
259
+ its(:index) { is_expected.to eq(
260
+ Daru::CategoricalIndex.new([:a, :a, :a])) }
261
+ end
262
+
263
+ context "single instance" do
264
+ subject { dv[:c] }
265
+
266
+ it { is_expected.to eq 'e' }
267
+ end
268
+ end
269
+
270
+ context "multiple categories" do
271
+ subject { dv[:a, :c] }
272
+
273
+ it { is_expected.to be_a Daru::Vector }
274
+ its(:size) { is_expected.to eq 4 }
275
+ its(:to_a) { is_expected.to eq ['a', 'c', 'd', 'e'] }
276
+ its(:index) { is_expected.to eq(
277
+ Daru::CategoricalIndex.new([:a, :a, :a, :c])) }
278
+ end
279
+
280
+ context "multiple positional indexes" do
281
+ subject { dv[0, 1, 2] }
282
+
283
+ it { is_expected.to be_a Daru::Vector }
284
+ its(:size) { is_expected.to eq 3 }
285
+ its(:to_a) { is_expected.to eq ['a', 'b', 'c'] }
286
+ its(:index) { is_expected.to eq(
287
+ Daru::CategoricalIndex.new([:a, :b, :a])) }
288
+ end
289
+
290
+ context "single positional index" do
291
+ subject { dv[1] }
292
+
293
+ it { is_expected.to eq 'b' }
294
+ end
295
+
296
+ context "invalid category" do
297
+ it { expect { dv[:x] }.to raise_error IndexError }
298
+ end
299
+
300
+ context "invalid positional index" do
301
+ it { expect { dv[30] }.to raise_error IndexError }
302
+ end
303
+ end
304
+
305
+ context "numerical index" do
306
+ let (:idx) { Daru::CategoricalIndex.new [1, 1, 2, 2, 3] }
307
+ let (:dv) { Daru::Vector.new 'a'..'e', index: idx }
308
+
309
+ context "single category" do
310
+ context "multiple instances" do
311
+ subject { dv[1] }
312
+
313
+ it { is_expected.to be_a Daru::Vector }
314
+ its(:size) { is_expected.to eq 2 }
315
+ its(:to_a) { is_expected.to eq ['a', 'b'] }
316
+ its(:index) { is_expected.to eq(
317
+ Daru::CategoricalIndex.new([1, 1])) }
318
+ end
319
+
320
+ context "single instance" do
321
+ subject { dv[3] }
322
+
323
+ it { is_expected.to eq 'e' }
324
+ end
325
+ end
326
+ end
327
+ end
328
+ end
329
+
330
+ context "#at" do
331
+ context Daru::Index do
332
+ let (:idx) { Daru::Index.new [1, 0, :c] }
333
+ let (:dv) { Daru::Vector.new ['a', 'b', 'c'], index: idx }
334
+
335
+ context "single position" do
336
+ it { expect(dv.at 1).to eq 'b' }
337
+ end
338
+
339
+ context "multiple positions" do
340
+ subject { dv.at 0, 2 }
341
+
342
+ it { is_expected.to be_a Daru::Vector }
343
+ its(:size) { is_expected.to eq 2 }
344
+ its(:to_a) { is_expected.to eq ['a', 'c'] }
345
+ its(:'index.to_a') { is_expected.to eq [1, :c] }
346
+ end
347
+
348
+ context "invalid position" do
349
+ it { expect { dv.at 3 }.to raise_error IndexError }
350
+ end
351
+
352
+ context "invalid positions" do
353
+ it { expect { dv.at 2, 3 }.to raise_error IndexError }
354
+ end
355
+
356
+ context "range" do
357
+ subject { dv.at 0..1 }
358
+
359
+ it { is_expected.to be_a Daru::Vector }
360
+ its(:size) { is_expected.to eq 2 }
361
+ its(:to_a) { is_expected.to eq ['a', 'b'] }
362
+ its(:'index.to_a') { is_expected.to eq [1, 0] }
363
+ end
364
+
365
+ context "range with negative end" do
366
+ subject { dv.at 0..-2 }
367
+
368
+ it { is_expected.to be_a Daru::Vector }
369
+ its(:size) { is_expected.to eq 2 }
370
+ its(:to_a) { is_expected.to eq ['a', 'b'] }
371
+ its(:'index.to_a') { is_expected.to eq [1, 0] }
372
+ end
373
+
374
+ context "range with single element" do
375
+ subject { dv.at 0..0 }
376
+
377
+ it { is_expected.to be_a Daru::Vector }
378
+ its(:size) { is_expected.to eq 1 }
379
+ its(:to_a) { is_expected.to eq ['a'] }
380
+ its(:'index.to_a') { is_expected.to eq [1] }
381
+ end
382
+ end
383
+
384
+ context Daru::MultiIndex do
385
+ let (:idx) do
386
+ Daru::MultiIndex.from_tuples [
387
+ [:a,:one,:bar],
388
+ [:a,:one,:baz],
389
+ [:b,:two,:bar],
390
+ [:a,:two,:baz],
391
+ ]
392
+ end
393
+ let (:dv) { Daru::Vector.new 1..4, index: idx }
394
+
395
+ context "single position" do
396
+ it { expect(dv.at 1).to eq 2 }
397
+ end
398
+
399
+ context "multiple positions" do
400
+ subject { dv.at 2, 3 }
401
+
402
+ it { is_expected.to be_a Daru::Vector }
403
+ its(:size) { is_expected.to eq 2 }
404
+ its(:to_a) { is_expected.to eq [3, 4] }
405
+ its(:'index.to_a') { is_expected.to eq [[:b, :two, :bar],
406
+ [:a, :two, :baz]] }
407
+ end
408
+
409
+ context "invalid position" do
410
+ it { expect { dv.at 4 }.to raise_error IndexError }
411
+ end
412
+
413
+ context "invalid positions" do
414
+ it { expect { dv.at 2, 4 }.to raise_error IndexError }
415
+ end
416
+
417
+ context "range" do
418
+ subject { dv.at 2..3 }
419
+
420
+ it { is_expected.to be_a Daru::Vector }
421
+ its(:size) { is_expected.to eq 2 }
422
+ its(:to_a) { is_expected.to eq [3, 4] }
423
+ its(:'index.to_a') { is_expected.to eq [[:b, :two, :bar],
424
+ [:a, :two, :baz]] }
425
+ end
426
+
427
+ context "range with negative end" do
428
+ subject { dv.at 2..-1 }
429
+
430
+ it { is_expected.to be_a Daru::Vector }
431
+ its(:size) { is_expected.to eq 2 }
432
+ its(:to_a) { is_expected.to eq [3, 4] }
433
+ its(:'index.to_a') { is_expected.to eq [[:b, :two, :bar],
434
+ [:a, :two, :baz]] }
435
+ end
436
+
437
+ context "range with single element" do
438
+ subject { dv.at 2..2 }
439
+
440
+ it { is_expected.to be_a Daru::Vector }
441
+ its(:size) { is_expected.to eq 1 }
442
+ its(:to_a) { is_expected.to eq [3] }
443
+ its(:'index.to_a') { is_expected.to eq [[:b, :two, :bar]] }
444
+ end
445
+ end
446
+
447
+ context Daru::CategoricalIndex do
448
+ let (:idx) { Daru::CategoricalIndex.new [:a, 1, 1, :a, :c] }
449
+ let (:dv) { Daru::Vector.new 'a'..'e', index: idx }
450
+
451
+ context "multiple positional indexes" do
452
+ subject { dv.at 0, 1, 2 }
453
+
454
+ it { is_expected.to be_a Daru::Vector }
455
+ its(:size) { is_expected.to eq 3 }
456
+ its(:to_a) { is_expected.to eq ['a', 'b', 'c'] }
457
+ its(:index) { is_expected.to eq(
458
+ Daru::CategoricalIndex.new([:a, 1, 1])) }
459
+ end
460
+
461
+ context "single positional index" do
462
+ subject { dv.at 1 }
463
+
464
+ it { is_expected.to eq 'b' }
465
+ end
466
+
467
+ context "invalid position" do
468
+ it { expect { dv.at 5 }.to raise_error IndexError }
469
+ end
470
+
471
+ context "invalid positions" do
472
+ it { expect { dv.at 2, 5 }.to raise_error IndexError }
473
+ end
474
+
475
+ context "range" do
476
+ subject { dv.at 0..2 }
477
+
478
+ it { is_expected.to be_a Daru::Vector }
479
+ its(:size) { is_expected.to eq 3 }
480
+ its(:to_a) { is_expected.to eq ['a', 'b', 'c'] }
481
+ its(:index) { is_expected.to eq(
482
+ Daru::CategoricalIndex.new([:a, 1, 1])) }
483
+ end
484
+
485
+ context "range with negative end" do
486
+ subject { dv.at 0..-3 }
487
+
488
+ it { is_expected.to be_a Daru::Vector }
489
+ its(:size) { is_expected.to eq 3 }
490
+ its(:to_a) { is_expected.to eq ['a', 'b', 'c'] }
491
+ its(:index) { is_expected.to eq(
492
+ Daru::CategoricalIndex.new([:a, 1, 1])) }
493
+ end
494
+
495
+ context "range with single element" do
496
+ subject { dv.at 0..0 }
497
+
498
+ it { is_expected.to be_a Daru::Vector }
499
+ its(:size) { is_expected.to eq 1 }
500
+ its(:to_a) { is_expected.to eq ['a'] }
501
+ its(:index) { is_expected.to eq(
502
+ Daru::CategoricalIndex.new([:a])) }
503
+ end
504
+ end
257
505
  end
258
506
 
259
507
  context "#[]=" do
@@ -339,6 +587,223 @@ describe Daru::Vector do
339
587
  expect(@vector).to eq(Daru::Vector.new([0,1,2,3,4,5,6,69,8,9,10,11],
340
588
  index: @multi_index, name: :precise_assignment, dtype: dtype))
341
589
  end
590
+
591
+ it "fails predictably on unknown index" do
592
+ expect { @vector[:d] = 69 }.to raise_error(IndexError)
593
+ expect { @vector[:b, :three] = 69 }.to raise_error(IndexError)
594
+ expect { @vector[:b, :two, :test] = 69 }.to raise_error(IndexError)
595
+ end
596
+ end
597
+
598
+ context Daru::CategoricalIndex do
599
+ context "non-numerical index" do
600
+ let (:idx) { Daru::CategoricalIndex.new [:a, :b, :a, :a, :c] }
601
+ let (:dv) { Daru::Vector.new 'a'..'e', index: idx }
602
+
603
+ context "single category" do
604
+ context "multiple instances" do
605
+ subject { dv }
606
+ before { dv[:a] = 'x' }
607
+
608
+ its(:size) { is_expected.to eq 5 }
609
+ its(:to_a) { is_expected.to eq ['x', 'b', 'x', 'x', 'e'] }
610
+ its(:index) { is_expected.to eq idx }
611
+ end
612
+
613
+ context "single instance" do
614
+ subject { dv }
615
+ before { dv[:b] = 'x' }
616
+
617
+ its(:size) { is_expected.to eq 5 }
618
+ its(:to_a) { is_expected.to eq ['a', 'x', 'c', 'd', 'e'] }
619
+ its(:index) { is_expected.to eq idx }
620
+ end
621
+ end
622
+
623
+ context "multiple categories" do
624
+ subject { dv }
625
+ before { dv[:a, :c] = 'x' }
626
+
627
+ its(:size) { is_expected.to eq 5 }
628
+ its(:to_a) { is_expected.to eq ['x', 'b', 'x', 'x', 'x'] }
629
+ its(:index) { is_expected.to eq idx }
630
+ end
631
+
632
+ context "multiple positional indexes" do
633
+ subject { dv }
634
+ before { dv[0, 1, 2] = 'x' }
635
+
636
+ its(:size) { is_expected.to eq 5 }
637
+ its(:to_a) { is_expected.to eq ['x', 'x', 'x', 'd', 'e'] }
638
+ its(:index) { is_expected.to eq idx }
639
+ end
640
+
641
+ context "single positional index" do
642
+ subject { dv }
643
+ before { dv[1] = 'x' }
644
+
645
+ its(:size) { is_expected.to eq 5 }
646
+ its(:to_a) { is_expected.to eq ['a', 'x', 'c', 'd', 'e'] }
647
+ its(:index) { is_expected.to eq idx }
648
+ end
649
+
650
+ context "invalid category" do
651
+ it { expect { dv[:x] = 'x' }.to raise_error IndexError }
652
+ end
653
+
654
+ context "invalid positional index" do
655
+ it { expect { dv[30] = 'x'}.to raise_error IndexError }
656
+ end
657
+ end
658
+
659
+ context "numerical index" do
660
+ let (:idx) { Daru::CategoricalIndex.new [1, 1, 2, 2, 3] }
661
+ let (:dv) { Daru::Vector.new 'a'..'e', index: idx }
662
+
663
+ context "single category" do
664
+ subject { dv }
665
+ before { dv[1] = 'x' }
666
+
667
+ its(:size) { is_expected.to eq 5 }
668
+ its(:to_a) { is_expected.to eq ['x', 'x', 'c', 'd', 'e'] }
669
+ its(:index) { is_expected.to eq idx }
670
+ end
671
+
672
+ context "multiple categories" do
673
+ subject { dv }
674
+ before { dv[1, 2] = 'x' }
675
+
676
+ its(:size) { is_expected.to eq 5 }
677
+ its(:to_a) { is_expected.to eq ['x', 'x', 'x', 'x', 'e'] }
678
+ its(:index) { is_expected.to eq idx }
679
+ end
680
+ end
681
+ end
682
+ end
683
+
684
+ context "#set_at" do
685
+ context Daru::Index do
686
+ let (:idx) { Daru::Index.new [1, 0, :c] }
687
+ let (:dv) { Daru::Vector.new ['a', 'b', 'c'], index: idx }
688
+
689
+ context "single position" do
690
+ subject { dv }
691
+ before { dv.set_at [1], 'x' }
692
+
693
+ its(:to_a) { is_expected.to eq ['a', 'x', 'c'] }
694
+ end
695
+
696
+ context "multiple positions" do
697
+ subject { dv }
698
+ before { dv.set_at [0, 2], 'x' }
699
+
700
+ its(:to_a) { is_expected.to eq ['x', 'b', 'x'] }
701
+ end
702
+
703
+ context "invalid position" do
704
+ it { expect { dv.set_at [3], 'x' }.to raise_error IndexError }
705
+ end
706
+
707
+ context "invalid positions" do
708
+ it { expect { dv.set_at [2, 3], 'x' }.to raise_error IndexError }
709
+ end
710
+ end
711
+
712
+ context Daru::MultiIndex do
713
+ let(:idx) do
714
+ Daru::MultiIndex.from_tuples [
715
+ [:a,:one,:bar],
716
+ [:a,:one,:baz],
717
+ [:b,:two,:bar],
718
+ [:a,:two,:baz],
719
+ ]
720
+ end
721
+ let(:dv) { Daru::Vector.new 1..4, index: idx }
722
+
723
+ context "single position" do
724
+ subject { dv }
725
+ before { dv.set_at [1], 'x' }
726
+
727
+ its(:to_a) { is_expected.to eq [1, 'x', 3, 4] }
728
+ end
729
+
730
+ context "multiple positions" do
731
+ subject { dv }
732
+ before { dv.set_at [2, 3], 'x' }
733
+
734
+ its(:to_a) { is_expected.to eq [1, 2, 'x', 'x'] }
735
+ end
736
+
737
+ context "invalid position" do
738
+ it { expect { dv.set_at [4], 'x' }.to raise_error IndexError }
739
+ end
740
+
741
+ context "invalid positions" do
742
+ it { expect { dv.set_at [2, 4], 'x' }.to raise_error IndexError }
743
+ end
744
+ end
745
+
746
+ context Daru::CategoricalIndex do
747
+ let (:idx) { Daru::CategoricalIndex.new [:a, 1, 1, :a, :c] }
748
+ let (:dv) { Daru::Vector.new 'a'..'e', index: idx }
749
+
750
+ context "multiple positional indexes" do
751
+ subject { dv }
752
+ before { dv.set_at [0, 1, 2], 'x' }
753
+
754
+ its(:to_a) { is_expected.to eq ['x', 'x', 'x', 'd', 'e'] }
755
+ end
756
+
757
+ context "single positional index" do
758
+ subject { dv }
759
+ before { dv.set_at [1], 'x' }
760
+
761
+ its(:to_a) { is_expected.to eq ['a', 'x', 'c', 'd', 'e'] }
762
+ end
763
+
764
+ context "invalid position" do
765
+ it { expect { dv.set_at [5], 'x' }.to raise_error IndexError }
766
+ end
767
+
768
+ context "invalid positions" do
769
+ it { expect { dv.set_at [2, 5], 'x' }.to raise_error IndexError }
770
+ end
771
+ end
772
+ end
773
+
774
+ context '#head' do
775
+ subject(:vector) do
776
+ Daru::Vector.new (1..20).to_a, dtype: dtype
777
+ end
778
+
779
+ it 'takes 10 by default' do
780
+ expect(vector.head).to eq Daru::Vector.new (1..10).to_a
781
+ end
782
+
783
+ it 'takes num if provided' do
784
+ expect(vector.head(3)).to eq Daru::Vector.new (1..3).to_a
785
+ end
786
+
787
+ it 'does not fail on too large num' do
788
+ expect(vector.head(3000)).to eq vector
789
+ end
790
+ end
791
+
792
+ context '#tail' do
793
+ subject(:vector) do
794
+ Daru::Vector.new (1..20).to_a, dtype: dtype
795
+ end
796
+
797
+ it 'takes 10 by default' do
798
+ expect(vector.tail).to eq Daru::Vector.new (11..20).to_a, index: (10..19).to_a
799
+ end
800
+
801
+ it 'takes num if provided' do
802
+ expect(vector.tail(3)).to eq Daru::Vector.new (18..20).to_a, index: (17..19).to_a
803
+ end
804
+
805
+ it 'does not fail on too large num' do
806
+ expect(vector.tail(3000)).to eq vector
342
807
  end
343
808
  end
344
809
 
@@ -446,6 +911,27 @@ describe Daru::Vector do
446
911
  end
447
912
  end
448
913
 
914
+ context "#to_df" do
915
+ let(:dv) { Daru::Vector.new(['a','b','c'], name: :my_dv, index: ['alpha', 'beta', 'gamma']) }
916
+ let(:df) { dv.to_df }
917
+
918
+ it 'is a dataframe' do
919
+ expect(df).to be_a Daru::DataFrame
920
+ end
921
+
922
+ it 'converts the vector to a single-vector dataframe' do
923
+ expect(df[:my_dv]).to eq dv
924
+ end
925
+
926
+ it 'has the same index as the original vector' do
927
+ expect(df.index).to eq dv.index
928
+ end
929
+
930
+ it 'has the same name as the vector' do
931
+ expect(df.name).to eq :my_dv
932
+ end
933
+ end
934
+
449
935
  context "#to_h" do
450
936
  context Daru::Index do
451
937
  it "returns the vector as a hash" do
@@ -477,17 +963,22 @@ describe Daru::Vector do
477
963
  end
478
964
  end
479
965
 
966
+ context "#to_json" do
967
+ subject(:vector) do
968
+ Daru::Vector.new [1,2,3,4,5], name: :a,
969
+ index: [:one, :two, :three, :four, :five], dtype: dtype
970
+ end
971
+
972
+ its(:to_json) { is_expected.to eq(vector.to_h.to_json) }
973
+ end
974
+
480
975
  context "#uniq" do
481
976
  before do
482
- @v = Daru::Vector.new [1, 2, 2, 2.0, 3, 3.0], index:[:a, :b, :c, :d, :e, :f], metadata: { cdc_type: 2 }
977
+ @v = Daru::Vector.new [1, 2, 2, 2.0, 3, 3.0], index:[:a, :b, :c, :d, :e, :f]
483
978
  end
484
979
  it "keeps only unique values" do
485
980
  expect(@v.uniq).to eq(Daru::Vector.new [1, 2, 2.0, 3, 3.0], index: [:a, :b, :d, :e, :f])
486
981
  end
487
-
488
- it "retains the original vector metadata" do
489
- expect(@v.uniq.metadata).to eq({ cdc_type: 2 })
490
- end
491
982
  end
492
983
 
493
984
  context "#cast" do
@@ -503,7 +994,7 @@ describe Daru::Vector do
503
994
  context "#sort" do
504
995
  context Daru::Index do
505
996
  before do
506
- @dv = Daru::Vector.new [33,2,15,332,1], name: :dv, index: [:a, :b, :c, :d, :e], metadata: { cdc_type: 2 }
997
+ @dv = Daru::Vector.new [33,2,15,332,1], name: :dv, index: [:a, :b, :c, :d, :e]
507
998
  end
508
999
 
509
1000
  it "sorts the vector with defaults and returns a new vector, preserving indexing" do
@@ -531,7 +1022,7 @@ describe Daru::Vector do
531
1022
  with_nils = Daru::Vector.new [22,4,nil,111,nil,2]
532
1023
 
533
1024
  expect(with_nils.sort(ascending: false)).to eq(
534
- Daru::Vector.new [nil,nil,111,22,4,2], index: [4,2,3,0,1,5])
1025
+ Daru::Vector.new [111,22,4,2,nil,nil], index: [3,0,1,5,4,2])
535
1026
  end
536
1027
 
537
1028
  it "correctly sorts vector in ascending order with non-numeric data and nils" do
@@ -545,11 +1036,7 @@ describe Daru::Vector do
545
1036
  non_numeric = Daru::Vector.new ['a','b', nil, 'aa', '1234', nil]
546
1037
 
547
1038
  expect(non_numeric.sort(ascending: false)).to eq(
548
- Daru::Vector.new [nil,nil,'b','aa','a','1234'], index: [5,2,1,3,0,4])
549
- end
550
-
551
- it "retains the original vector metadata" do
552
- expect(@dv.sort.metadata).to eq({ cdc_type: 2 })
1039
+ Daru::Vector.new ['b','aa','a','1234',nil,nil], index: [1,3,0,4,5,2])
553
1040
  end
554
1041
  end
555
1042
 
@@ -602,6 +1089,79 @@ describe Daru::Vector do
602
1089
  [0,22,44,-56,111], index: mi_abs, name: :sort_abs, dtype: dtype))
603
1090
  end
604
1091
  end
1092
+
1093
+ context Daru::CategoricalIndex do
1094
+ let(:idx) { Daru::CategoricalIndex.new [:a, 1, :a, 1, :c] }
1095
+ let(:dv_numeric) { Daru::Vector.new [4, 5, 3, 2, 1], index: idx }
1096
+ let(:dv_string) { Daru::Vector.new ['xxxx', 'zzzzz', 'ccc', 'bb', 'a'], index: idx }
1097
+ let(:dv_nil) { Daru::Vector.new [3, nil, 2, 1, -1], index: idx }
1098
+
1099
+ context "increasing order" do
1100
+ context "numeric" do
1101
+ subject { dv_numeric.sort }
1102
+
1103
+ its(:size) { is_expected.to eq 5 }
1104
+ its(:to_a) { is_expected.to eq [1, 2, 3, 4, 5] }
1105
+ its(:'index.to_a') { is_expected.to eq [:c, 1, :a, :a, 1] }
1106
+ end
1107
+
1108
+ context "non-numeric" do
1109
+ subject { dv_string.sort }
1110
+
1111
+ its(:size) { is_expected.to eq 5 }
1112
+ its(:to_a) { is_expected.to eq ['a', 'bb', 'ccc', 'xxxx', 'zzzzz'] }
1113
+ its(:'index.to_a') { is_expected.to eq [:c, 1, :a, :a, 1] }
1114
+ end
1115
+
1116
+ context "block" do
1117
+ subject { dv_string.sort { |a, b| a.length <=> b.length } }
1118
+
1119
+ its(:to_a) { is_expected.to eq ['a', 'bb', 'ccc', 'xxxx', 'zzzzz'] }
1120
+ its(:'index.to_a') { is_expected.to eq [:c, 1, :a, :a, 1] }
1121
+ end
1122
+
1123
+ context "nils" do
1124
+ subject { dv_nil.sort }
1125
+
1126
+ its(:to_a) { is_expected.to eq [nil, -1, 1, 2, 3] }
1127
+ its(:'index.to_a') { is_expected.to eq [1, :c, 1, :a, :a] }
1128
+ end
1129
+ end
1130
+
1131
+ context "decreasing order" do
1132
+ context "numeric" do
1133
+ subject { dv_numeric.sort(ascending: false) }
1134
+
1135
+ its(:size) { is_expected.to eq 5 }
1136
+ its(:to_a) { is_expected.to eq [5, 4, 3, 2, 1] }
1137
+ its(:'index.to_a') { is_expected.to eq [1, :a, :a, 1, :c] }
1138
+ end
1139
+
1140
+ context "non-numeric" do
1141
+ subject { dv_string.sort(ascending: false) }
1142
+
1143
+ its(:size) { is_expected.to eq 5 }
1144
+ its(:to_a) { is_expected.to eq ['zzzzz', 'xxxx', 'ccc', 'bb', 'a'] }
1145
+ its(:'index.to_a') { is_expected.to eq [1, :a, :a, 1, :c] }
1146
+ end
1147
+
1148
+ context "block" do
1149
+ subject do
1150
+ dv_string.sort(ascending: false) { |a, b| a.length <=> b.length }
1151
+ end
1152
+
1153
+ its(:to_a) { is_expected.to eq ['zzzzz', 'xxxx', 'ccc', 'bb', 'a'] }
1154
+ its(:'index.to_a') { is_expected.to eq [1, :a, :a, 1, :c] }
1155
+ end
1156
+
1157
+ context "nils" do
1158
+ subject { dv_nil.sort(ascending: false) }
1159
+
1160
+ its(:to_a) { is_expected.to eq [3, 2, 1, -1, nil] }
1161
+ its(:'index.to_a') { is_expected.to eq [:a, :a, 1, :c, 1] }
1162
+ end
1163
+ end
1164
+ end
605
1165
  end
606
1166
 
607
1167
  context "#index=" do
@@ -624,23 +1184,32 @@ describe Daru::Vector do
624
1184
  end
625
1185
  end
626
1186
 
1187
+ context "#reindex!" do
1188
+ before do
1189
+ @vector = Daru::Vector.new([1,2,3,4,5])
1190
+ @index = Daru::Index.new([3,4,1,0,6])
1191
+ end
1192
+ it "intelligently reindexes" do
1193
+ @vector.reindex!(@index)
1194
+ expect(@vector).to eq(
1195
+ Daru::Vector.new([4,5,2,1,nil], index: @index))
1196
+ end
1197
+ end
1198
+
627
1199
  context "#reindex" do
628
1200
  before do
629
- @vector = Daru::Vector.new([1,2,3,4,5], metadata: { cdc_type: 2 })
1201
+ @vector = Daru::Vector.new([1,2,3,4,5])
630
1202
  @index = Daru::Index.new([3,4,1,0,6])
631
1203
  end
632
1204
  it "intelligently reindexes" do
633
1205
  expect(@vector.reindex(@index)).to eq(
634
1206
  Daru::Vector.new([4,5,2,1,nil], index: @index))
635
1207
  end
636
- it "retains the original vector metadata" do
637
- expect(@vector.reindex(@index).metadata).to eq({ cdc_type: 2 })
638
- end
639
1208
  end
640
1209
 
641
1210
  context "#dup" do
642
1211
  before do
643
- @dv = Daru::Vector.new [1,2], name: :yoda, metadata: { cdc_type: 2 }, index: [:happy, :lightsaber]
1212
+ @dv = Daru::Vector.new [1,2], name: :yoda, index: [:happy, :lightsaber]
644
1213
  end
645
1214
 
646
1215
  it "copies the original data" do
@@ -655,14 +1224,6 @@ describe Daru::Vector do
655
1224
  expect(@dv.dup.name).to eq(:yoda)
656
1225
  end
657
1226
 
658
- it "copies the original vector metadata" do
659
- expect(@dv.dup.metadata).to eq({ cdc_type: 2 })
660
- end
661
-
662
- it "creates a new metadata object" do
663
- expect(@dv.dup.metadata.object_id).not_to eq(@dv.metadata.object_id)
664
- end
665
-
666
1227
  it "copies the original index" do
667
1228
  expect(@dv.dup.index).to eq(Daru::Index.new([:happy, :lightsaber]))
668
1229
  end
@@ -786,70 +1347,39 @@ describe Daru::Vector do
786
1347
  end
787
1348
  end
788
1349
 
789
- context "#missing_values" do
790
- before do
791
- @common = Daru::Vector.new([5, 5, 5, 5, 5, 6, 6, 7, 8, 9, 10, 1, 2, 3, 4, nil, -99, -99])
792
- end
793
-
794
- it "allows setting the value to be treated as missing" do
795
- @common.missing_values = [10]
796
- expect(@common.only_valid.to_a.sort).to eq(
797
- [-99, -99, 1, 2, 3, 4, 5, 5, 5, 5, 5, 6, 6, 7, 8, 9]
798
- )
799
- expect(@common.to_a).to eq(
800
- [5, 5, 5, 5, 5, 6, 6, 7, 8, 9, 10, 1, 2, 3, 4, nil, -99, -99]
801
- )
802
-
803
- @common.missing_values = [-99]
804
- expect(@common.only_valid.to_a.sort).to eq(
805
- [1, 2, 3, 4, 5, 5, 5, 5, 5, 6, 6, 7, 8, 9, 10]
806
- )
807
- expect(@common.to_a).to eq(
808
- [5, 5, 5, 5, 5, 6, 6, 7, 8, 9, 10, 1, 2, 3, 4, nil, -99, -99]
809
- )
810
-
811
- @common.missing_values = []
812
- expect(@common.only_valid.to_a.sort).to eq(
813
- [-99, -99, 1, 2, 3, 4, 5, 5, 5, 5, 5, 6, 6, 7, 8, 9, 10]
814
- )
815
- expect(@common.to_a).to eq(
816
- [5, 5, 5, 5, 5, 6, 6, 7, 8, 9, 10, 1, 2, 3, 4, nil, -99, -99]
817
- )
1350
+ context "#is_nil?" do
1351
+ before(:each) do
1352
+ @with_md = Daru::Vector.new([1,2,nil,3,4,nil])
1353
+ @without_md = Daru::Vector.new([1,2,3,4,5,6])
818
1354
  end
819
1355
 
820
- it "responds to has_missing_data? with explicit missing_values" do
821
- a = Daru::Vector.new [1,2,3,4,10]
822
- a.missing_values = [10]
823
-
824
- expect(a.has_missing_data?).to eq(true)
1356
+ it "verifies missing data presence" do
1357
+ expect(@with_md.is_nil?) .to eq(Daru::Vector.new([false,false,true,false,false,true]))
1358
+ expect(@without_md.is_nil?).to eq(Daru::Vector.new([false,false,false,false,false,false]))
825
1359
  end
826
1360
  end
827
1361
 
828
- context "#is_nil?" do
1362
+ context "#not_nil?" do
829
1363
  before(:each) do
830
1364
  @with_md = Daru::Vector.new([1,2,nil,3,4,nil])
831
1365
  @without_md = Daru::Vector.new([1,2,3,4,5,6])
832
1366
  end
833
1367
 
834
1368
  it "verifies missing data presence" do
835
- expect(@with_md.is_nil?) .to eq(Daru::Vector.new([false,false,true,false,false,true]))
836
- expect(@without_md.is_nil?).to eq(Daru::Vector.new([false,false,false,false,false,false]))
1369
+ expect(@with_md.not_nil?) .to eq(Daru::Vector.new([true,true,false,true,true,false]))
1370
+ expect(@without_md.not_nil?).to eq(Daru::Vector.new([true,true,true,true,true,true]))
837
1371
  end
838
1372
  end
839
1373
 
840
1374
  context "#clone_structure" do
841
1375
  context Daru::Index do
842
1376
  before do
843
- @vec = Daru::Vector.new([1,2,3,4,5], metadata: { cdc_type: 2 }, index: [:a,:b,:c,:d,:e])
1377
+ @vec = Daru::Vector.new([1,2,3,4,5], index: [:a,:b,:c,:d,:e])
844
1378
  end
845
1379
 
846
1380
  it "clones a vector with its index and fills it with nils" do
847
1381
  expect(@vec.clone_structure).to eq(Daru::Vector.new([nil,nil,nil,nil,nil], index: [:a,:b,:c,:d,:e]))
848
1382
  end
849
-
850
- it "retains the original vector metadata" do
851
- expect(@vec.clone_structure.metadata).to eq({ cdc_type: 2 })
852
- end
853
1383
  end
854
1384
 
855
1385
  context Daru::MultiIndex do
@@ -857,25 +1387,187 @@ describe Daru::Vector do
857
1387
  end
858
1388
  end
859
1389
 
860
- context "#missing_positions" do
861
- context Daru::Index do
862
- before(:each) do
863
- @with_md = Daru::Vector.new([1,2,nil,3,4,nil])
1390
+ context '#reject_values'do
1391
+ let(:dv) { Daru::Vector.new [1, nil, 3, :a, Float::NAN, nil, Float::NAN, 1],
1392
+ index: 11..18 }
1393
+ context 'reject only nils' do
1394
+ subject { dv.reject_values nil }
1395
+
1396
+ it { is_expected.to be_a Daru::Vector }
1397
+ its(:to_a) { is_expected.to eq [1, 3, :a, Float::NAN, Float::NAN, 1] }
1398
+ its(:'index.to_a') { is_expected.to eq [11, 13, 14, 15, 17, 18] }
1399
+ end
1400
+
1401
+ context 'reject only float::NAN' do
1402
+ subject { dv.reject_values Float::NAN }
1403
+
1404
+ it { is_expected.to be_a Daru::Vector }
1405
+ its(:to_a) { is_expected.to eq [1, nil, 3, :a, nil, 1] }
1406
+ its(:'index.to_a') { is_expected.to eq [11, 12, 13, 14, 16, 18] }
1407
+ end
1408
+
1409
+ context 'reject both nil and float::NAN' do
1410
+ subject { dv.reject_values nil, Float::NAN }
1411
+
1412
+ it { is_expected.to be_a Daru::Vector }
1413
+ its(:to_a) { is_expected.to eq [1, 3, :a, 1] }
1414
+ its(:'index.to_a') { is_expected.to eq [11, 13, 14, 18] }
1415
+ end
1416
+
1417
+ context 'reject any other value' do
1418
+ subject { dv.reject_values 1, 3 }
1419
+
1420
+ it { is_expected.to be_a Daru::Vector }
1421
+ its(:to_a) { is_expected.to eq [nil, :a, Float::NAN, nil, Float::NAN] }
1422
+ its(:'index.to_a') { is_expected.to eq [12, 14, 15, 16, 17] }
1423
+ end
1424
+
1425
+ context 'when resultant vector has only one value' do
1426
+ subject { dv.reject_values 1, :a, nil, Float::NAN }
1427
+
1428
+ it { is_expected.to be_a Daru::Vector }
1429
+ its(:to_a) { is_expected.to eq [3] }
1430
+ its(:'index.to_a') { is_expected.to eq [13] }
1431
+ end
1432
+
1433
+ context 'when resultant vector has no value' do
1434
+ subject { dv.reject_values 1, 3, :a, nil, Float::NAN, 5 }
1435
+
1436
+ it { is_expected.to be_a Daru::Vector }
1437
+ its(:to_a) { is_expected.to eq [] }
1438
+ its(:'index.to_a') { is_expected.to eq [] }
1439
+ end
1440
+
1441
+ context 'works for gsl' do
1442
+ let(:dv) { Daru::Vector.new [1, 2, 3, Float::NAN], dtype: :gsl,
1443
+ index: 11..14 }
1444
+ subject { dv.reject_values Float::NAN }
1445
+
1446
+ it { is_expected.to be_a Daru::Vector }
1447
+ its(:dtype) { is_expected.to eq :gsl }
1448
+ its(:to_a) { is_expected.to eq [1, 2, 3].map(&:to_f) }
1449
+ its(:'index.to_a') { is_expected.to eq [11, 12, 13] }
1450
+ end
1451
+
1452
+ context 'test caching' do
1453
+ let(:dv) { Daru::Vector.new [nil]*8, index: 11..18}
1454
+ before do
1455
+ dv.reject_values nil
1456
+ [1, nil, 3, :a, Float::NAN, nil, Float::NAN, 1].each_with_index do |v, pos|
1457
+ dv.set_at [pos], v
1458
+ end
1459
+ end
1460
+
1461
+ context 'reject only nils' do
1462
+ subject { dv.reject_values nil }
1463
+
1464
+ it { is_expected.to be_a Daru::Vector }
1465
+ its(:to_a) { is_expected.to eq [1, 3, :a, Float::NAN, Float::NAN, 1] }
1466
+ its(:'index.to_a') { is_expected.to eq [11, 13, 14, 15, 17, 18] }
1467
+ end
1468
+
1469
+ context 'reject only float::NAN' do
1470
+ subject { dv.reject_values Float::NAN }
1471
+
1472
+ it { is_expected.to be_a Daru::Vector }
1473
+ its(:to_a) { is_expected.to eq [1, nil, 3, :a, nil, 1] }
1474
+ its(:'index.to_a') { is_expected.to eq [11, 12, 13, 14, 16, 18] }
864
1475
  end
1476
+
1477
+ context 'reject both nil and float::NAN' do
1478
+ subject { dv.reject_values nil, Float::NAN }
1479
+
1480
+ it { is_expected.to be_a Daru::Vector }
1481
+ its(:to_a) { is_expected.to eq [1, 3, :a, 1] }
1482
+ its(:'index.to_a') { is_expected.to eq [11, 13, 14, 18] }
1483
+ end
1484
+
1485
+ context 'reject any other value' do
1486
+ subject { dv.reject_values 1, 3 }
1487
+
1488
+ it { is_expected.to be_a Daru::Vector }
1489
+ its(:to_a) { is_expected.to eq [nil, :a, Float::NAN, nil, Float::NAN] }
1490
+ its(:'index.to_a') { is_expected.to eq [12, 14, 15, 16, 17] }
1491
+ end
1492
+ end
1493
+ end
865
1494
 
866
- it "returns the indexes of nils" do
867
- expect(@with_md.missing_positions).to eq([2,5])
1495
+ context '#include_values?' do
1496
+ context 'only nils' do
1497
+ context 'true' do
1498
+ let(:dv) { Daru::Vector.new [1, 2, 3, :a, 'Unknown', nil] }
1499
+ it { expect(dv.include_values? nil).to eq true }
868
1500
  end
869
1501
 
870
- it "updates after assingment" do
871
- @with_md[3] = nil
872
- expect(@with_md.missing_positions).to eq([2,3,5])
1502
+ context 'false' do
1503
+ let(:dv) { Daru::Vector.new [1, 2, 3, :a, 'Unknown'] }
1504
+ it { expect(dv.include_values? nil).to eq false }
873
1505
  end
874
1506
  end
875
1507
 
1508
+ context 'only Float::NAN' do
1509
+ context 'true' do
1510
+ let(:dv) { Daru::Vector.new [1, nil, 2, 3, Float::NAN] }
1511
+ it { expect(dv.include_values? Float::NAN).to eq true }
1512
+ end
1513
+
1514
+ context 'false' do
1515
+ let(:dv) { Daru::Vector.new [1, nil, 2, 3] }
1516
+ it { expect(dv.include_values? Float::NAN).to eq false }
1517
+ end
1518
+ end
1519
+
1520
+ context 'both nil and Float::NAN' do
1521
+ context 'true with only nil' do
1522
+ let(:dv) { Daru::Vector.new [1, Float::NAN, 2, 3] }
1523
+ it { expect(dv.include_values? nil, Float::NAN).to eq true }
1524
+ end
1525
+
1526
+ context 'true with only Float::NAN' do
1527
+ let(:dv) { Daru::Vector.new [1, nil, 2, 3] }
1528
+ it { expect(dv.include_values? nil, Float::NAN).to eq true }
1529
+ end
1530
+
1531
+ context 'false' do
1532
+ let(:dv) { Daru::Vector.new [1, 2, 3] }
1533
+ it { expect(dv.include_values? nil, Float::NAN).to eq false }
1534
+ end
1535
+ end
1536
+
1537
+ context 'any other value' do
1538
+ context 'true' do
1539
+ let(:dv) { Daru::Vector.new [1, 2, 3, 4, nil] }
1540
+ it { expect(dv.include_values? 1, 2, 3, 5).to eq true }
1541
+ end
1542
+
1543
+ context 'false' do
1544
+ let(:dv) { Daru::Vector.new [1, 2, 3, 4, nil] }
1545
+ it { expect(dv.include_values? 5, 6).to eq false }
1546
+ end
1547
+ end
1548
+ end
1549
+
1550
+ context '#count_values' do
1551
+ let(:dv) { Daru::Vector.new [1, 2, 3, 1, 2, nil, nil] }
1552
+ it { expect(dv.count_values 1, 2).to eq 4 }
1553
+ it { expect(dv.count_values nil).to eq 2 }
1554
+ it { expect(dv.count_values 3, Float::NAN).to eq 1 }
1555
+ it { expect(dv.count_values 4).to eq 0 }
1556
+ end
1557
+
1558
+ context '#indexes' do
1559
+ context Daru::Index do
1560
+ let(:dv) { Daru::Vector.new [1, 2, 1, 2, 3, nil, nil, Float::NAN],
1561
+ index: 11..18 }
1562
+
1563
+ subject { dv.indexes 1, 2, nil, Float::NAN }
1564
+ it { is_expected.to be_a Array }
1565
+ it { is_expected.to eq [11, 12, 13, 14, 16, 17, 18] }
1566
+ end
1567
+
876
1568
  context Daru::MultiIndex do
877
- it "returns indexes of nils" do
878
- mi = Daru::MultiIndex.from_tuples([
1569
+ let(:mi) do
1570
+ Daru::MultiIndex.from_tuples([
879
1571
  ['M', 2000],
880
1572
  ['M', 2001],
881
1573
  ['M', 2002],
@@ -884,14 +1576,47 @@ describe Daru::Vector do
884
1576
  ['F', 2001],
885
1577
  ['F', 2002],
886
1578
  ['F', 2003]
887
- ])
888
- vector = Daru::Vector.new([nil,2,4,5,3,nil,2,nil], index: mi)
889
- expect(vector.missing_positions).to eq([
890
- ['M',2000],
891
- ['F',2001],
892
- ['F',2003]
893
1579
  ])
894
1580
  end
1581
+ let(:dv) { Daru::Vector.new [1, 2, 1, 2, 3, nil, nil, Float::NAN],
1582
+ index: mi }
1583
+
1584
+ subject { dv.indexes 1, 2, Float::NAN }
1585
+ it { is_expected.to be_a Array }
1586
+ it { is_expected.to eq(
1587
+ [
1588
+ ['M', 2000],
1589
+ ['M', 2001],
1590
+ ['M', 2002],
1591
+ ['M', 2003],
1592
+ ['F', 2003]
1593
+ ]) }
1594
+ end
1595
+ end
1596
+
1597
+ context '#replace_values' do
1598
+ subject do
1599
+ Daru::Vector.new(
1600
+ [1, 2, 1, 4, nil, Float::NAN, nil, Float::NAN],
1601
+ index: 11..18
1602
+ )
1603
+ end
1604
+
1605
+ context 'replace nils and NaNs' do
1606
+ before { subject.replace_values [nil, Float::NAN], 10 }
1607
+ its(:to_a) { is_expected.to eq [1, 2, 1, 4, 10, 10, 10, 10] }
1608
+ end
1609
+
1610
+ context 'replace arbitrary values' do
1611
+ before { subject.replace_values [1, 2], 10 }
1612
+ its(:to_a) { is_expected.to eq(
1613
+ [10, 10, 10, 4, nil, Float::NAN, nil, Float::NAN]) }
1614
+ end
1615
+
1616
+ context 'works for single value' do
1617
+ before { subject.replace_values nil, 10 }
1618
+ its(:to_a) { is_expected.to eq(
1619
+ [1, 2, 1, 4, 10, Float::NAN, 10, Float::NAN]) }
895
1620
  end
896
1621
  end
897
1622
 
@@ -967,25 +1692,38 @@ describe Daru::Vector do
967
1692
  it "converts Daru::Vector to a vertical Ruby Matrix" do
968
1693
  expect(@vector.to_matrix(:vertical)).to eq(Matrix.columns([[1,2,3,4,5,6]]))
969
1694
  end
970
- end
971
1695
 
972
- context "#only_valid" do
973
- [:array, :gsl].each do |dtype|
974
- describe dtype do
975
- before do
976
- @vector = Daru::Vector.new [1,2,3,4,5,3,5], metadata: { cdc_type: 2 },
977
- index: [:a, :b, :c, :d, :e, :f, :g], dtype: dtype, missing_values: [3, 5]
978
- end
1696
+ it 'raises on wrong axis' do
1697
+ expect { @vector.to_matrix(:strange) }.to raise_error(ArgumentError)
1698
+ end
1699
+ end
979
1700
 
980
- it "returns a Vector of only non-missing data" do
981
- expect(@vector.only_valid).to eq(Daru::Vector.new([1,2,4],
982
- index: [:a, :b, :d], dtype: dtype))
983
- end
1701
+ context '#to_nmatrix' do
1702
+ let(:dv) { Daru::Vector.new [1, 2, 3, 4, 5] }
1703
+
1704
+ context 'horizontal axis' do
1705
+ subject { dv.to_nmatrix }
984
1706
 
985
- it "retains the original vector metadata" do
986
- expect(@vector.only_valid.metadata).to eq({ cdc_type: 2 })
987
- end
988
- end
1707
+ it { is_expected.to be_a NMatrix }
1708
+ its(:shape) { is_expected.to eq [1, 5] }
1709
+ its(:to_a) { is_expected.to eq [1, 2, 3, 4, 5] }
1710
+ end
1711
+
1712
+ context 'vertical axis' do
1713
+ subject { dv.to_nmatrix :vertical }
1714
+
1715
+ it { is_expected.to be_a NMatrix }
1716
+ its(:shape) { is_expected.to eq [5, 1] }
1717
+ its(:to_a) { is_expected.to eq [1, 2, 3, 4, 5].map { |i| [i] } }
1718
+ end
1719
+
1720
+ context 'invalid axis' do
1721
+ it { expect { dv.to_nmatrix :hello }.to raise_error ArgumentError }
1722
+ end
1723
+
1724
+ context 'vector contain non-numeric' do
1725
+ let(:dv) { Daru::Vector.new [1, 2, nil, 4] }
1726
+ it { expect { dv.to_nmatrix }.to raise_error ArgumentError }
989
1727
  end
990
1728
  end
991
1729
 
@@ -1054,17 +1792,10 @@ describe Daru::Vector do
1054
1792
  end
1055
1793
  end
1056
1794
 
1057
- context "#n_valid" do
1058
- it "returns number of non-missing positions" do
1059
- v = Daru::Vector.new [1,2,3,4,nil,nil,3,5]
1060
- expect(v.n_valid).to eq(6)
1061
- end
1062
- end
1063
-
1064
1795
  context "#reset_index!" do
1065
1796
  it "resets any index to a numerical serialized index" do
1066
1797
  v = Daru::Vector.new([1,2,3,4,5,nil,nil,4,nil])
1067
- r = v.only_valid.reset_index!
1798
+ r = v.reject_values(*Daru::MISSING_VALUES).reset_index!
1068
1799
  expect(r).to eq(Daru::Vector.new([1,2,3,4,5,4]))
1069
1800
  expect(r.index).to eq(Daru::Index.new([0,1,2,3,4,5]))
1070
1801
 
@@ -1087,6 +1818,10 @@ describe Daru::Vector do
1087
1818
  @v.rename "This is a vector"
1088
1819
  expect(@v.name).to eq("This is a vector")
1089
1820
  end
1821
+
1822
+ it "returns vector" do
1823
+ expect(@v.rename 'hello').to be_a Daru::Vector
1824
+ end
1090
1825
  end
1091
1826
 
1092
1827
  context "#any?" do
@@ -1117,16 +1852,6 @@ describe Daru::Vector do
1117
1852
  end
1118
1853
  end
1119
1854
 
1120
- context "#only_missing" do
1121
- it "returns a vector (with proper index) of all the elements marked 'missing'" do
1122
- v = Daru::Vector.new([1,2,3,4,5,6,4,5,5,4,4,nil,nil,nil])
1123
- v.missing_values = [nil, 5]
1124
-
1125
- expect(v.only_missing).to eq(Daru::Vector.new([5,5,5,nil,nil,nil],
1126
- index: [4,7,8,11,12,13]))
1127
- end
1128
- end
1129
-
1130
1855
  context "#detach_index" do
1131
1856
  it "creates a DataFrame with first Vector as index and second as values of the Vector" do
1132
1857
  v = Daru::Vector.new([1,2,3,4,5,6],
@@ -1141,7 +1866,7 @@ describe Daru::Vector do
1141
1866
  context "#lag" do
1142
1867
  before do
1143
1868
  @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,
1144
- 16.86, 16.86, 16.56, 16.36, 16.66, 16.77], metadata: { cdc_type: 2 })
1869
+ 16.86, 16.86, 16.56, 16.36, 16.66, 16.77])
1145
1870
  end
1146
1871
 
1147
1872
  it "lags the vector by specified amount" do
@@ -1156,16 +1881,58 @@ describe Daru::Vector do
1156
1881
  expect(lag2[lag2.size - 1]).to be_within(0.001).of(16.36)
1157
1882
  expect(lag2[lag2.size - 2]).to be_within(0.001).of(16.56)
1158
1883
  end
1884
+ end
1885
+
1886
+ context '#method_missing' do
1887
+ context 'getting' do
1888
+ subject(:vector) { Daru::Vector.new [1,2,3], index: [:a, :b, :c] }
1159
1889
 
1160
- it "retains the original vector metadata" do
1161
- expect(@xiu.lag(1).metadata).to eq({ cdc_type: 2 })
1890
+ it 'returns value for existing index' do
1891
+ expect(vector.a).to eq 1
1892
+ end
1893
+
1894
+ it 'raises on getting non-existent index' do
1895
+ expect { vector.d }.to raise_error NoMethodError
1896
+ end
1897
+
1898
+ it 'sets existing index' do
1899
+ vector.a = 5
1900
+ expect(vector[:a]).to eq 5
1901
+ end
1902
+
1903
+ it 'raises on non-existent index setting' do
1904
+ # FIXME: inconsistency between IndexError here and NoMethodError on getting - zverok
1905
+ expect { vector.d = 5 }.to raise_error IndexError
1906
+ end
1162
1907
  end
1163
1908
  end
1164
1909
 
1165
- context "#metadata" do
1166
- it "defaults to an empty hash for metadata" do
1167
- dv = Daru::Vector.new [1,2,3,4,5]
1168
- expect(dv.metadata).to eq({})
1910
+ context '#db_type' do
1911
+ it 'is DATE for vector with any date in it' do
1912
+ # FIXME: is it sane?.. - zverok
1913
+ expect(Daru::Vector.new(['2016-03-01', 'foo', 4]).db_type).to eq 'DATE'
1914
+ end
1915
+
1916
+ it 'is INTEGER for digits-only values' do
1917
+ expect(Daru::Vector.new(['123', 456, 789]).db_type).to eq 'INTEGER'
1918
+ end
1919
+
1920
+ it 'is DOUBLE for digits-and-point values' do
1921
+ expect(Daru::Vector.new(['123.4', 456, 789e-10]).db_type).to eq 'DOUBLE'
1922
+ end
1923
+
1924
+ it 'is VARCHAR for everyting else' do
1925
+ expect(Daru::Vector.new(['123 and stuff', 456, 789e-10]).db_type).to eq 'VARCHAR (255)'
1926
+ end
1927
+ end
1928
+
1929
+ context 'on wrong dtypes' do
1930
+ it 'should not accept mdarray' do
1931
+ expect { Daru::Vector.new([], dtype: :mdarray) }.to raise_error(NotImplementedError)
1932
+ end
1933
+
1934
+ it 'should not accept anything else' do
1935
+ expect { Daru::Vector.new([], dtype: :kittens) }.to raise_error(ArgumentError)
1169
1936
  end
1170
1937
  end
1171
1938