daru 0.1.3.1 → 0.1.4

Sign up to get free protection for your applications and to get access to all the features.
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