daru_lite 0.1

Sign up to get free protection for your applications and to get access to all the features.
Files changed (149) hide show
  1. checksums.yaml +7 -0
  2. data/.github/ISSUE_TEMPLATE.md +18 -0
  3. data/.github/workflows/ci.yml +33 -0
  4. data/.gitignore +10 -0
  5. data/.rspec +2 -0
  6. data/.rubocop.yml +27 -0
  7. data/.rubocop_todo.yml +137 -0
  8. data/CONTRIBUTING.md +47 -0
  9. data/Gemfile +2 -0
  10. data/History.md +4 -0
  11. data/LICENSE +24 -0
  12. data/README.md +218 -0
  13. data/Rakefile +69 -0
  14. data/ReleasePolicy.md +20 -0
  15. data/benchmarks/TradeoffData.csv +65 -0
  16. data/benchmarks/csv_reading.rb +22 -0
  17. data/benchmarks/dataframe_creation.rb +39 -0
  18. data/benchmarks/db_loading.rb +34 -0
  19. data/benchmarks/duplicating.rb +45 -0
  20. data/benchmarks/group_by.rb +32 -0
  21. data/benchmarks/joining.rb +52 -0
  22. data/benchmarks/row_access.rb +41 -0
  23. data/benchmarks/row_assign.rb +36 -0
  24. data/benchmarks/sorting.rb +51 -0
  25. data/benchmarks/statistics.rb +28 -0
  26. data/benchmarks/vector_access.rb +31 -0
  27. data/benchmarks/vector_assign.rb +42 -0
  28. data/benchmarks/where_clause.rb +48 -0
  29. data/benchmarks/where_vs_filter.rb +28 -0
  30. data/daru_lite.gemspec +55 -0
  31. data/images/README.md +5 -0
  32. data/images/con0.png +0 -0
  33. data/images/con1.png +0 -0
  34. data/images/init0.png +0 -0
  35. data/images/init1.png +0 -0
  36. data/images/man0.png +0 -0
  37. data/images/man1.png +0 -0
  38. data/images/man2.png +0 -0
  39. data/images/man3.png +0 -0
  40. data/images/man4.png +0 -0
  41. data/images/man5.png +0 -0
  42. data/images/man6.png +0 -0
  43. data/lib/daru_lite/accessors/array_wrapper.rb +109 -0
  44. data/lib/daru_lite/accessors/dataframe_by_row.rb +25 -0
  45. data/lib/daru_lite/accessors/mdarray_wrapper.rb +7 -0
  46. data/lib/daru_lite/category.rb +929 -0
  47. data/lib/daru_lite/configuration.rb +34 -0
  48. data/lib/daru_lite/core/group_by.rb +403 -0
  49. data/lib/daru_lite/core/merge.rb +270 -0
  50. data/lib/daru_lite/core/query.rb +109 -0
  51. data/lib/daru_lite/dataframe.rb +3080 -0
  52. data/lib/daru_lite/date_time/index.rb +569 -0
  53. data/lib/daru_lite/date_time/offsets.rb +397 -0
  54. data/lib/daru_lite/exceptions.rb +2 -0
  55. data/lib/daru_lite/extensions/which_dsl.rb +53 -0
  56. data/lib/daru_lite/formatters/table.rb +52 -0
  57. data/lib/daru_lite/helpers/array.rb +53 -0
  58. data/lib/daru_lite/index/categorical_index.rb +201 -0
  59. data/lib/daru_lite/index/index.rb +374 -0
  60. data/lib/daru_lite/index/multi_index.rb +374 -0
  61. data/lib/daru_lite/io/csv/converters.rb +21 -0
  62. data/lib/daru_lite/io/io.rb +294 -0
  63. data/lib/daru_lite/io/sql_data_source.rb +97 -0
  64. data/lib/daru_lite/iruby/helpers.rb +38 -0
  65. data/lib/daru_lite/iruby/templates/dataframe.html.erb +5 -0
  66. data/lib/daru_lite/iruby/templates/dataframe_mi.html.erb +5 -0
  67. data/lib/daru_lite/iruby/templates/dataframe_mi_tbody.html.erb +35 -0
  68. data/lib/daru_lite/iruby/templates/dataframe_mi_thead.html.erb +21 -0
  69. data/lib/daru_lite/iruby/templates/dataframe_tbody.html.erb +28 -0
  70. data/lib/daru_lite/iruby/templates/dataframe_thead.html.erb +21 -0
  71. data/lib/daru_lite/iruby/templates/multi_index.html.erb +12 -0
  72. data/lib/daru_lite/iruby/templates/vector.html.erb +5 -0
  73. data/lib/daru_lite/iruby/templates/vector_mi.html.erb +5 -0
  74. data/lib/daru_lite/iruby/templates/vector_mi_tbody.html.erb +26 -0
  75. data/lib/daru_lite/iruby/templates/vector_mi_thead.html.erb +8 -0
  76. data/lib/daru_lite/iruby/templates/vector_tbody.html.erb +17 -0
  77. data/lib/daru_lite/iruby/templates/vector_thead.html.erb +8 -0
  78. data/lib/daru_lite/maths/arithmetic/dataframe.rb +91 -0
  79. data/lib/daru_lite/maths/arithmetic/vector.rb +117 -0
  80. data/lib/daru_lite/maths/statistics/dataframe.rb +202 -0
  81. data/lib/daru_lite/maths/statistics/vector.rb +1019 -0
  82. data/lib/daru_lite/monkeys.rb +56 -0
  83. data/lib/daru_lite/vector.rb +1678 -0
  84. data/lib/daru_lite/version.rb +3 -0
  85. data/lib/daru_lite.rb +99 -0
  86. data/profile/_base.rb +23 -0
  87. data/profile/df_to_a.rb +10 -0
  88. data/profile/filter.rb +13 -0
  89. data/profile/joining.rb +13 -0
  90. data/profile/sorting.rb +12 -0
  91. data/profile/vector_each_with_index.rb +9 -0
  92. data/profile/vector_new.rb +9 -0
  93. data/spec/accessors/array_wrapper_spec.rb +3 -0
  94. data/spec/category_spec.rb +1741 -0
  95. data/spec/core/group_by_spec.rb +655 -0
  96. data/spec/core/merge_spec.rb +179 -0
  97. data/spec/core/query_spec.rb +347 -0
  98. data/spec/daru_lite_spec.rb +22 -0
  99. data/spec/dataframe_spec.rb +4330 -0
  100. data/spec/date_time/data_spec.rb +197 -0
  101. data/spec/date_time/date_time_index_helper_spec.rb +72 -0
  102. data/spec/date_time/index_spec.rb +588 -0
  103. data/spec/date_time/offsets_spec.rb +465 -0
  104. data/spec/extensions/which_dsl_spec.rb +38 -0
  105. data/spec/fixtures/bank2.dat +200 -0
  106. data/spec/fixtures/boolean_converter_test.csv +5 -0
  107. data/spec/fixtures/countries.json +7794 -0
  108. data/spec/fixtures/duplicates.csv +32 -0
  109. data/spec/fixtures/eciresults.html +394 -0
  110. data/spec/fixtures/empties.dat +2 -0
  111. data/spec/fixtures/empty_rows_test.csv +17 -0
  112. data/spec/fixtures/macau.html +3691 -0
  113. data/spec/fixtures/macd_data.csv +150 -0
  114. data/spec/fixtures/matrix_test.csv +100 -0
  115. data/spec/fixtures/moneycontrol.html +6812 -0
  116. data/spec/fixtures/music_data.tsv +2501 -0
  117. data/spec/fixtures/repeated_fields.csv +7 -0
  118. data/spec/fixtures/sales-funnel.csv +18 -0
  119. data/spec/fixtures/scientific_notation.csv +4 -0
  120. data/spec/fixtures/string_converter_test.csv +5 -0
  121. data/spec/fixtures/strings.dat +2 -0
  122. data/spec/fixtures/test_xls.xls +0 -0
  123. data/spec/fixtures/test_xls_2.xls +0 -0
  124. data/spec/fixtures/url_test.txt~ +0 -0
  125. data/spec/fixtures/valid_markup.html +62 -0
  126. data/spec/fixtures/wiki_climate.html +1243 -0
  127. data/spec/fixtures/wiki_table_info.html +631 -0
  128. data/spec/formatters/table_formatter_spec.rb +137 -0
  129. data/spec/helpers_spec.rb +8 -0
  130. data/spec/index/categorical_index_spec.rb +170 -0
  131. data/spec/index/index_spec.rb +417 -0
  132. data/spec/index/multi_index_spec.rb +680 -0
  133. data/spec/io/io_spec.rb +373 -0
  134. data/spec/io/sql_data_source_spec.rb +56 -0
  135. data/spec/iruby/dataframe_spec.rb +170 -0
  136. data/spec/iruby/helpers_spec.rb +49 -0
  137. data/spec/iruby/multi_index_spec.rb +37 -0
  138. data/spec/iruby/vector_spec.rb +105 -0
  139. data/spec/maths/arithmetic/dataframe_spec.rb +148 -0
  140. data/spec/maths/arithmetic/vector_spec.rb +165 -0
  141. data/spec/maths/statistics/dataframe_spec.rb +178 -0
  142. data/spec/maths/statistics/vector_spec.rb +756 -0
  143. data/spec/monkeys_spec.rb +42 -0
  144. data/spec/shared/vector_display_spec.rb +213 -0
  145. data/spec/spec_helper.rb +87 -0
  146. data/spec/support/database_helper.rb +30 -0
  147. data/spec/support/matchers.rb +5 -0
  148. data/spec/vector_spec.rb +2293 -0
  149. metadata +571 -0
@@ -0,0 +1,2293 @@
1
+ require 'spec_helper.rb'
2
+
3
+ describe DaruLite::Vector do
4
+ ALL_DTYPES.each do |dtype|
5
+ describe dtype.to_s do
6
+ before do
7
+ @common_all_dtypes = DaruLite::Vector.new(
8
+ [5, 5, 5, 5, 5, 6, 6, 7, 8, 9, 10, 1, 2, 3, 4, 11, -99, -99],
9
+ dtype: dtype, name: :common_all_dtypes)
10
+ end
11
+
12
+ context "#initialize" do
13
+ before do
14
+ @tuples = [
15
+ [:a, :one, :foo],
16
+ [:a, :two, :bar],
17
+ [:b, :one, :bar],
18
+ [:b, :two, :baz]
19
+ ]
20
+
21
+ @multi_index = DaruLite::MultiIndex.from_tuples(@tuples)
22
+ end
23
+
24
+ it "initializes from an Array" do
25
+ dv = DaruLite::Vector.new [1,2,3,4,5], name: :ravan,
26
+ index: [:ek, :don, :teen, :char, :pach], dtype: dtype
27
+
28
+ expect(dv.name) .to eq(:ravan)
29
+ expect(dv.index).to eq(DaruLite::Index.new [:ek, :don, :teen, :char, :pach])
30
+ end
31
+
32
+ it "accepts Index object" do
33
+ idx = DaruLite::Index.new [:yoda, :anakin, :obi, :padme, :r2d2]
34
+ dv = DaruLite::Vector.new [1,2,3,4,5], name: :yoga, index: idx, dtype: dtype
35
+
36
+ expect(dv.name) .to eq(:yoga)
37
+ expect(dv.index).to eq(idx)
38
+ end
39
+
40
+ it "accepts a MultiIndex object" do
41
+ dv = DaruLite::Vector.new [1,2,3,4], name: :mi, index: @multi_index, dtype: dtype
42
+
43
+ expect(dv.name).to eq(:mi)
44
+ expect(dv.index).to eq(@multi_index)
45
+ end
46
+
47
+ it "raises error for improper Index" do
48
+ expect {
49
+ dv = DaruLite::Vector.new [1,2,3,4,5], name: :yoga, index: [:i, :j, :k]
50
+ }.to raise_error
51
+
52
+ expect {
53
+ idx = DaruLite::Index.new [:i, :j, :k]
54
+ dv = DaruLite::Vector.new [1,2,3,4,5], name: :yoda, index: idx, dtype: dtype
55
+ }.to raise_error
56
+ end
57
+
58
+ it "raises error for improper MultiIndex" do
59
+ expect {
60
+ dv = DaruLite::Vector.new [1,2,3,4,5], name: :mi, index: @multi_index
61
+ }.to raise_error
62
+ end
63
+
64
+ it "initializes without specifying an index" do
65
+ dv = DaruLite::Vector.new [1,2,3,4,5], name: :vishnu, dtype: dtype
66
+
67
+ expect(dv.index).to eq(DaruLite::Index.new [0,1,2,3,4])
68
+ end
69
+
70
+ it "inserts nils for extra indices" do
71
+ dv = DaruLite::Vector.new [1,2,3], name: :yoga, index: [0,1,2,3,4], dtype: dtype
72
+
73
+ expect(dv).to eq([1,2,3,nil,nil].dv(:yoga,nil, :array))
74
+ end
75
+
76
+ it "inserts nils for extra indices (MultiIndex)" do
77
+ dv = DaruLite::Vector.new [1,2], name: :mi, index: @multi_index, dtype: :array
78
+ expect(dv).to eq(DaruLite::Vector.new([1,2,nil,nil], name: :mi, index: @multi_index, dtype: :array))
79
+ end
80
+
81
+ it "accepts all sorts of objects for indexing" do
82
+ dv = DaruLite::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
86
+ end
87
+
88
+ context "#reorder!" do
89
+ let(:vector_with_dtype) do
90
+ DaruLite::Vector.new(
91
+ [1, 2, 3, 4],
92
+ index: [:a, :b, :c, :d],
93
+ dtype: dtype)
94
+ end
95
+ let(:arranged_vector) do
96
+ DaruLite::Vector.new([4,3,2,1], index: [:d, :c, :b, :a], dtype: dtype)
97
+ end
98
+
99
+ before do
100
+ vector_with_dtype.reorder! [3, 2, 1, 0]
101
+ end
102
+
103
+ it "rearranges with passed order" do
104
+ expect(vector_with_dtype).to eq arranged_vector
105
+ end
106
+
107
+ it "doesn't change dtype" do
108
+ expect(vector_with_dtype.data.class).to eq arranged_vector.data.class
109
+ end
110
+ end
111
+
112
+ context ".new_with_size" do
113
+ it "creates new vector from only size" do
114
+ v1 = DaruLite::Vector.new 10.times.map { nil }, dtype: dtype
115
+ v2 = DaruLite::Vector.new_with_size 10, dtype: dtype
116
+ expect(v2).to eq(v1)
117
+ end if dtype == :array
118
+
119
+ it "creates new vector from only size and value" do
120
+ a = rand
121
+ v1 = DaruLite::Vector.new 10.times.map { a }, dtype: dtype
122
+ v2 = DaruLite::Vector.new_with_size(10, value: a, dtype: dtype)
123
+ expect(v2).to eq(v1)
124
+ end
125
+
126
+ it "accepts block" do
127
+ v1 = DaruLite::Vector.new 10.times.map {|i| i * 2 }
128
+ v2 = DaruLite::Vector.new_with_size(10, dtype: dtype) { |i| i * 2 }
129
+ expect(v2).to eq(v1)
130
+ end
131
+ end
132
+
133
+ context ".[]" do
134
+ it "returns same results as R-c()" do
135
+ reference = DaruLite::Vector.new([0, 4, 5, 6, 10])
136
+ expect(DaruLite::Vector[0, 4, 5, 6, 10]) .to eq(reference)
137
+ expect(DaruLite::Vector[0, 4..6, 10]) .to eq(reference)
138
+ expect(DaruLite::Vector[[0], [4, 5, 6], [10]]) .to eq(reference)
139
+ expect(DaruLite::Vector[[0], [4, [5, [6]]], [10]]).to eq(reference)
140
+
141
+ expect(DaruLite::Vector[[0], DaruLite::Vector.new([4, 5, 6]), [10]])
142
+ .to eq(reference)
143
+ end
144
+ end
145
+
146
+ context "#[]" do
147
+ context DaruLite::Index do
148
+ before :each do
149
+ @dv = DaruLite::Vector.new [1,2,3,4,5], name: :yoga,
150
+ index: [:yoda, :anakin, :obi, :padme, :r2d2], dtype: dtype
151
+ end
152
+
153
+ it "returns an element after passing an index" do
154
+ expect(@dv[:yoda]).to eq(1)
155
+ end
156
+
157
+ it "returns an element after passing a numeric index" do
158
+ expect(@dv[0]).to eq(1)
159
+ end
160
+
161
+ it "returns a vector with given indices for multiple indices" do
162
+ expect(@dv[:yoda, :anakin]).to eq(DaruLite::Vector.new([1,2], name: :yoda,
163
+ index: [:yoda, :anakin], dtype: dtype))
164
+ end
165
+
166
+ it "returns a vector with given indices for multiple numeric indices" do
167
+ expect(@dv[0,1]).to eq(DaruLite::Vector.new([1,2], name: :yoda,
168
+ index: [:yoda, :anakin], dtype: dtype))
169
+ end
170
+
171
+ it "returns a vector when specified symbol Range" do
172
+ expect(@dv[:yoda..:anakin]).to eq(DaruLite::Vector.new([1,2],
173
+ index: [:yoda, :anakin], name: :yoga, dtype: dtype))
174
+ end
175
+
176
+ it "returns a vector when specified numeric Range" do
177
+ expect(@dv[3..4]).to eq(DaruLite::Vector.new([4,5], name: :yoga,
178
+ index: [:padme, :r2d2], dtype: dtype))
179
+ end
180
+
181
+ it "returns correct results for index of multiple index" do
182
+ v = DaruLite::Vector.new([1,2,3,4], index: ['a','c',1,:a])
183
+ expect(v['a']).to eq(1)
184
+ expect(v[:a]).to eq(4)
185
+ expect(v[1]).to eq(3)
186
+ expect(v[0]).to eq(1)
187
+ end
188
+
189
+ it "raises exception for invalid index" do
190
+ expect { @dv[:foo] }.to raise_error(IndexError)
191
+ expect { @dv[:obi, :foo] }.to raise_error(IndexError)
192
+ end
193
+ end
194
+
195
+ context DaruLite::MultiIndex do
196
+ before do
197
+ @tuples = [
198
+ [:a,:one,:bar],
199
+ [:a,:one,:baz],
200
+ [:a,:two,:bar],
201
+ [:a,:two,:baz],
202
+ [:b,:one,:bar],
203
+ [:b,:two,:bar],
204
+ [:b,:two,:baz],
205
+ [:b,:one,:foo],
206
+ [:c,:one,:bar],
207
+ [:c,:one,:baz],
208
+ [:c,:two,:foo],
209
+ [:c,:two,:bar],
210
+ [:d,:one,:foo]
211
+ ]
212
+ @multi_index = DaruLite::MultiIndex.from_tuples(@tuples)
213
+ @vector = DaruLite::Vector.new(
214
+ Array.new(13) { |i| i }, index: @multi_index,
215
+ dtype: dtype, name: :mi_vector)
216
+ end
217
+
218
+ it "returns a single element when passed a row number" do
219
+ expect(@vector[1]).to eq(1)
220
+ end
221
+
222
+ it "returns a single element when passed the full tuple" do
223
+ expect(@vector[:a, :one, :baz]).to eq(1)
224
+ end
225
+
226
+ it "returns sub vector when passed first layer of tuple" do
227
+ mi = DaruLite::MultiIndex.from_tuples([
228
+ [:one,:bar],
229
+ [:one,:baz],
230
+ [:two,:bar],
231
+ [:two,:baz]])
232
+ expect(@vector[:a]).to eq(DaruLite::Vector.new([0,1,2,3], index: mi,
233
+ dtype: dtype, name: :sub_vector))
234
+ end
235
+
236
+ it "returns sub vector when passed first and second layer of tuple" do
237
+ mi = DaruLite::MultiIndex.from_tuples([
238
+ [:foo],
239
+ [:bar]])
240
+ expect(@vector[:c,:two]).to eq(DaruLite::Vector.new([10,11], index: mi,
241
+ dtype: dtype, name: :sub_sub_vector))
242
+ end
243
+
244
+ it "returns sub vector not a single element when passed the partial tuple" do
245
+ mi = DaruLite::MultiIndex.from_tuples([[:foo]])
246
+ expect(@vector[:d, :one]).to eq(DaruLite::Vector.new([12], index: mi,
247
+ dtype: dtype, name: :sub_sub_vector))
248
+ end
249
+
250
+ it "returns a vector with corresponding MultiIndex when specified numeric Range" do
251
+ mi = DaruLite::MultiIndex.from_tuples([
252
+ [:a,:two,:baz],
253
+ [:b,:one,:bar],
254
+ [:b,:two,:bar],
255
+ [:b,:two,:baz],
256
+ [:b,:one,:foo],
257
+ [:c,:one,:bar],
258
+ [:c,:one,:baz]
259
+ ])
260
+ expect(@vector[3..9]).to eq(DaruLite::Vector.new([3,4,5,6,7,8,9], index: mi,
261
+ dtype: dtype, name: :slice))
262
+ end
263
+
264
+ it "raises exception for invalid index" do
265
+ expect { @vector[:foo] }.to raise_error(IndexError)
266
+ expect { @vector[:a, :two, :foo] }.to raise_error(IndexError)
267
+ expect { @vector[:x, :one] }.to raise_error(IndexError)
268
+ end
269
+ end
270
+
271
+ context DaruLite::CategoricalIndex do
272
+ # before { skip }
273
+ context "non-numerical index" do
274
+ let (:idx) { DaruLite::CategoricalIndex.new [:a, :b, :a, :a, :c] }
275
+ let (:dv) { DaruLite::Vector.new 'a'..'e', index: idx }
276
+
277
+ context "single category" do
278
+ context "multiple instances" do
279
+ subject { dv[:a] }
280
+
281
+ it { is_expected.to be_a DaruLite::Vector }
282
+ its(:size) { is_expected.to eq 3 }
283
+ its(:to_a) { is_expected.to eq ['a', 'c', 'd'] }
284
+ its(:index) { is_expected.to eq(
285
+ DaruLite::CategoricalIndex.new([:a, :a, :a])) }
286
+ end
287
+
288
+ context "single instance" do
289
+ subject { dv[:c] }
290
+
291
+ it { is_expected.to eq 'e' }
292
+ end
293
+ end
294
+
295
+ context "multiple categories" do
296
+ subject { dv[:a, :c] }
297
+
298
+ it { is_expected.to be_a DaruLite::Vector }
299
+ its(:size) { is_expected.to eq 4 }
300
+ its(:to_a) { is_expected.to eq ['a', 'c', 'd', 'e'] }
301
+ its(:index) { is_expected.to eq(
302
+ DaruLite::CategoricalIndex.new([:a, :a, :a, :c])) }
303
+ end
304
+
305
+ context "multiple positional indexes" do
306
+ subject { dv[0, 1, 2] }
307
+
308
+ it { is_expected.to be_a DaruLite::Vector }
309
+ its(:size) { is_expected.to eq 3 }
310
+ its(:to_a) { is_expected.to eq ['a', 'b', 'c'] }
311
+ its(:index) { is_expected.to eq(
312
+ DaruLite::CategoricalIndex.new([:a, :b, :a])) }
313
+ end
314
+
315
+ context "single positional index" do
316
+ subject { dv[1] }
317
+
318
+ it { is_expected.to eq 'b' }
319
+ end
320
+
321
+ context "invalid category" do
322
+ it { expect { dv[:x] }.to raise_error IndexError }
323
+ end
324
+
325
+ context "invalid positional index" do
326
+ it { expect { dv[30] }.to raise_error IndexError }
327
+ end
328
+ end
329
+
330
+ context "numerical index" do
331
+ let (:idx) { DaruLite::CategoricalIndex.new [1, 1, 2, 2, 3] }
332
+ let (:dv) { DaruLite::Vector.new 'a'..'e', index: idx }
333
+
334
+ context "single category" do
335
+ context "multiple instances" do
336
+ subject { dv[1] }
337
+
338
+ it { is_expected.to be_a DaruLite::Vector }
339
+ its(:size) { is_expected.to eq 2 }
340
+ its(:to_a) { is_expected.to eq ['a', 'b'] }
341
+ its(:index) { is_expected.to eq(
342
+ DaruLite::CategoricalIndex.new([1, 1])) }
343
+ end
344
+
345
+ context "single instance" do
346
+ subject { dv[3] }
347
+
348
+ it { is_expected.to eq 'e' }
349
+ end
350
+ end
351
+ end
352
+ end
353
+ end
354
+
355
+ context "#at" do
356
+ context DaruLite::Index do
357
+ let (:idx) { DaruLite::Index.new [1, 0, :c] }
358
+ let (:dv) { DaruLite::Vector.new ['a', 'b', 'c'], index: idx }
359
+
360
+ let (:idx_dt) { DaruLite::DateTimeIndex.new(['2017-01-01', '2017-02-01', '2017-03-01']) }
361
+ let (:dv_dt) { DaruLite::Vector.new(['a', 'b', 'c'], index: idx_dt) }
362
+
363
+ context "single position" do
364
+ it { expect(dv.at 1).to eq 'b' }
365
+ end
366
+
367
+ context "multiple positions" do
368
+ subject { dv.at 0, 2 }
369
+
370
+ it { is_expected.to be_a DaruLite::Vector }
371
+ its(:size) { is_expected.to eq 2 }
372
+ its(:to_a) { is_expected.to eq ['a', 'c'] }
373
+ its(:'index.to_a') { is_expected.to eq [1, :c] }
374
+ end
375
+
376
+ context "invalid position" do
377
+ it { expect { dv.at 3 }.to raise_error IndexError }
378
+ end
379
+
380
+ context "invalid positions" do
381
+ it { expect { dv.at 2, 3 }.to raise_error IndexError }
382
+ end
383
+
384
+ context "range" do
385
+ subject { dv.at 0..1 }
386
+
387
+ it { is_expected.to be_a DaruLite::Vector }
388
+ its(:size) { is_expected.to eq 2 }
389
+ its(:to_a) { is_expected.to eq ['a', 'b'] }
390
+ its(:'index.to_a') { is_expected.to eq [1, 0] }
391
+ end
392
+
393
+ context "range with negative end" do
394
+ subject { dv.at 0..-2 }
395
+
396
+ it { is_expected.to be_a DaruLite::Vector }
397
+ its(:size) { is_expected.to eq 2 }
398
+ its(:to_a) { is_expected.to eq ['a', 'b'] }
399
+ its(:'index.to_a') { is_expected.to eq [1, 0] }
400
+ end
401
+
402
+ context "range with single element" do
403
+ subject { dv.at 0..0 }
404
+
405
+ it { is_expected.to be_a DaruLite::Vector }
406
+ its(:size) { is_expected.to eq 1 }
407
+ its(:to_a) { is_expected.to eq ['a'] }
408
+ its(:'index.to_a') { is_expected.to eq [1] }
409
+ end
410
+
411
+ context "Splat .at on DateTime index" do
412
+ subject { dv_dt.at(*[1,2]) }
413
+
414
+ it { is_expected.to be_a DaruLite::Vector }
415
+ its(:size) { is_expected.to eq 2 }
416
+ its(:to_a) { is_expected.to eq ['b', 'c'] }
417
+ its(:'index.to_a') { is_expected.to eq ['2017-02-01', '2017-03-01'] }
418
+ end
419
+ end
420
+
421
+ context DaruLite::MultiIndex do
422
+ let (:idx) do
423
+ DaruLite::MultiIndex.from_tuples [
424
+ [:a,:one,:bar],
425
+ [:a,:one,:baz],
426
+ [:b,:two,:bar],
427
+ [:a,:two,:baz],
428
+ ]
429
+ end
430
+ let (:dv) { DaruLite::Vector.new 1..4, index: idx }
431
+
432
+ context "single position" do
433
+ it { expect(dv.at 1).to eq 2 }
434
+ end
435
+
436
+ context "multiple positions" do
437
+ subject { dv.at 2, 3 }
438
+
439
+ it { is_expected.to be_a DaruLite::Vector }
440
+ its(:size) { is_expected.to eq 2 }
441
+ its(:to_a) { is_expected.to eq [3, 4] }
442
+ its(:'index.to_a') { is_expected.to eq [[:b, :two, :bar],
443
+ [:a, :two, :baz]] }
444
+ end
445
+
446
+ context "invalid position" do
447
+ it { expect { dv.at 4 }.to raise_error IndexError }
448
+ end
449
+
450
+ context "invalid positions" do
451
+ it { expect { dv.at 2, 4 }.to raise_error IndexError }
452
+ end
453
+
454
+ context "range" do
455
+ subject { dv.at 2..3 }
456
+
457
+ it { is_expected.to be_a DaruLite::Vector }
458
+ its(:size) { is_expected.to eq 2 }
459
+ its(:to_a) { is_expected.to eq [3, 4] }
460
+ its(:'index.to_a') { is_expected.to eq [[:b, :two, :bar],
461
+ [:a, :two, :baz]] }
462
+ end
463
+
464
+ context "range with negative end" do
465
+ subject { dv.at 2..-1 }
466
+
467
+ it { is_expected.to be_a DaruLite::Vector }
468
+ its(:size) { is_expected.to eq 2 }
469
+ its(:to_a) { is_expected.to eq [3, 4] }
470
+ its(:'index.to_a') { is_expected.to eq [[:b, :two, :bar],
471
+ [:a, :two, :baz]] }
472
+ end
473
+
474
+ context "range with single element" do
475
+ subject { dv.at 2..2 }
476
+
477
+ it { is_expected.to be_a DaruLite::Vector }
478
+ its(:size) { is_expected.to eq 1 }
479
+ its(:to_a) { is_expected.to eq [3] }
480
+ its(:'index.to_a') { is_expected.to eq [[:b, :two, :bar]] }
481
+ end
482
+ end
483
+
484
+ context DaruLite::CategoricalIndex do
485
+ let (:idx) { DaruLite::CategoricalIndex.new [:a, 1, 1, :a, :c] }
486
+ let (:dv) { DaruLite::Vector.new 'a'..'e', index: idx }
487
+
488
+ context "multiple positional indexes" do
489
+ subject { dv.at 0, 1, 2 }
490
+
491
+ it { is_expected.to be_a DaruLite::Vector }
492
+ its(:size) { is_expected.to eq 3 }
493
+ its(:to_a) { is_expected.to eq ['a', 'b', 'c'] }
494
+ its(:index) { is_expected.to eq(
495
+ DaruLite::CategoricalIndex.new([:a, 1, 1])) }
496
+ end
497
+
498
+ context "single positional index" do
499
+ subject { dv.at 1 }
500
+
501
+ it { is_expected.to eq 'b' }
502
+ end
503
+
504
+ context "invalid position" do
505
+ it { expect { dv.at 5 }.to raise_error IndexError }
506
+ end
507
+
508
+ context "invalid positions" do
509
+ it { expect { dv.at 2, 5 }.to raise_error IndexError }
510
+ end
511
+
512
+ context "range" do
513
+ subject { dv.at 0..2 }
514
+
515
+ it { is_expected.to be_a DaruLite::Vector }
516
+ its(:size) { is_expected.to eq 3 }
517
+ its(:to_a) { is_expected.to eq ['a', 'b', 'c'] }
518
+ its(:index) { is_expected.to eq(
519
+ DaruLite::CategoricalIndex.new([:a, 1, 1])) }
520
+ end
521
+
522
+ context "range with negative end" do
523
+ subject { dv.at 0..-3 }
524
+
525
+ it { is_expected.to be_a DaruLite::Vector }
526
+ its(:size) { is_expected.to eq 3 }
527
+ its(:to_a) { is_expected.to eq ['a', 'b', 'c'] }
528
+ its(:index) { is_expected.to eq(
529
+ DaruLite::CategoricalIndex.new([:a, 1, 1])) }
530
+ end
531
+
532
+ context "range with single element" do
533
+ subject { dv.at 0..0 }
534
+
535
+ it { is_expected.to be_a DaruLite::Vector }
536
+ its(:size) { is_expected.to eq 1 }
537
+ its(:to_a) { is_expected.to eq ['a'] }
538
+ its(:index) { is_expected.to eq(
539
+ DaruLite::CategoricalIndex.new([:a])) }
540
+ end
541
+ end
542
+ end
543
+
544
+ context "#[]=" do
545
+ context DaruLite::Index do
546
+ before :each do
547
+ @dv = DaruLite::Vector.new [1,2,3,4,5], name: :yoga,
548
+ index: [:yoda, :anakin, :obi, :padme, :r2d2], dtype: dtype
549
+ end
550
+
551
+ it "assigns at the specified index" do
552
+ @dv[:yoda] = 666
553
+ expect(@dv[:yoda]).to eq(666)
554
+ end
555
+
556
+ it "assigns at the specified Integer index" do
557
+ @dv[0] = 666
558
+ expect(@dv[:yoda]).to eq(666)
559
+ end
560
+
561
+ it "sets dtype to Array if a nil is assigned" do
562
+ @dv[0] = nil
563
+ expect(@dv.dtype).to eq(:array)
564
+ end
565
+
566
+ it "assigns correctly for a mixed index Vector" do
567
+ v = DaruLite::Vector.new [1,2,3,4], index: ['a',:a,0,66]
568
+ v['a'] = 666
569
+ expect(v['a']).to eq(666)
570
+
571
+ v[0] = 666
572
+ expect(v[0]).to eq(666)
573
+
574
+ v[3] = 666
575
+ expect(v[3]).to eq(666)
576
+
577
+ expect(v).to eq(DaruLite::Vector.new([666,2,666,666],
578
+ index: ['a',:a,0,66]))
579
+ end
580
+ end
581
+
582
+ context DaruLite::MultiIndex do
583
+ before :each do
584
+ @tuples = [
585
+ [:a,:one,:bar],
586
+ [:a,:one,:baz],
587
+ [:a,:two,:bar],
588
+ [:a,:two,:baz],
589
+ [:b,:one,:bar],
590
+ [:b,:two,:bar],
591
+ [:b,:two,:baz],
592
+ [:b,:one,:foo],
593
+ [:c,:one,:bar],
594
+ [:c,:one,:baz],
595
+ [:c,:two,:foo],
596
+ [:c,:two,:bar]
597
+ ]
598
+ @multi_index = DaruLite::MultiIndex.from_tuples(@tuples)
599
+ @vector = DaruLite::Vector.new Array.new(12) { |i| i }, index: @multi_index,
600
+ dtype: dtype, name: :mi_vector
601
+ end
602
+
603
+ it "assigns all lower layer indices when specified a first layer index" do
604
+ @vector[:b] = 69
605
+ expect(@vector).to eq(DaruLite::Vector.new([0,1,2,3,69,69,69,69,8,9,10,11],
606
+ index: @multi_index, name: :top_layer_assignment, dtype: dtype
607
+ ))
608
+ end
609
+
610
+ it "assigns all lower indices when specified first and second layer index" do
611
+ @vector[:b, :one] = 69
612
+ expect(@vector).to eq(DaruLite::Vector.new([0,1,2,3,69,5,6,69,8,9,10,11],
613
+ index: @multi_index, name: :second_layer_assignment, dtype: dtype))
614
+ end
615
+
616
+ it "assigns just the precise value when specified complete tuple" do
617
+ @vector[:b, :one, :foo] = 69
618
+ expect(@vector).to eq(DaruLite::Vector.new([0,1,2,3,4,5,6,69,8,9,10,11],
619
+ index: @multi_index, name: :precise_assignment, dtype: dtype))
620
+ end
621
+
622
+ it "assigns correctly when numeric index" do
623
+ @vector[7] = 69
624
+ expect(@vector).to eq(DaruLite::Vector.new([0,1,2,3,4,5,6,69,8,9,10,11],
625
+ index: @multi_index, name: :precise_assignment, dtype: dtype))
626
+ end
627
+
628
+ it "fails predictably on unknown index" do
629
+ expect { @vector[:d] = 69 }.to raise_error(IndexError)
630
+ expect { @vector[:b, :three] = 69 }.to raise_error(IndexError)
631
+ expect { @vector[:b, :two, :test] = 69 }.to raise_error(IndexError)
632
+ end
633
+ end
634
+
635
+ context DaruLite::CategoricalIndex do
636
+ context "non-numerical index" do
637
+ let (:idx) { DaruLite::CategoricalIndex.new [:a, :b, :a, :a, :c] }
638
+ let (:dv) { DaruLite::Vector.new 'a'..'e', index: idx }
639
+
640
+ context "single category" do
641
+ context "multiple instances" do
642
+ subject { dv }
643
+ before { dv[:a] = 'x' }
644
+
645
+ its(:size) { is_expected.to eq 5 }
646
+ its(:to_a) { is_expected.to eq ['x', 'b', 'x', 'x', 'e'] }
647
+ its(:index) { is_expected.to eq idx }
648
+ end
649
+
650
+ context "single instance" do
651
+ subject { dv }
652
+ before { dv[:b] = 'x' }
653
+
654
+ its(:size) { is_expected.to eq 5 }
655
+ its(:to_a) { is_expected.to eq ['a', 'x', 'c', 'd', 'e'] }
656
+ its(:index) { is_expected.to eq idx }
657
+ end
658
+ end
659
+
660
+ context "multiple categories" do
661
+ subject { dv }
662
+ before { dv[:a, :c] = 'x' }
663
+
664
+ its(:size) { is_expected.to eq 5 }
665
+ its(:to_a) { is_expected.to eq ['x', 'b', 'x', 'x', 'x'] }
666
+ its(:index) { is_expected.to eq idx }
667
+ end
668
+
669
+ context "multiple positional indexes" do
670
+ subject { dv }
671
+ before { dv[0, 1, 2] = 'x' }
672
+
673
+ its(:size) { is_expected.to eq 5 }
674
+ its(:to_a) { is_expected.to eq ['x', 'x', 'x', 'd', 'e'] }
675
+ its(:index) { is_expected.to eq idx }
676
+ end
677
+
678
+ context "single positional index" do
679
+ subject { dv }
680
+ before { dv[1] = 'x' }
681
+
682
+ its(:size) { is_expected.to eq 5 }
683
+ its(:to_a) { is_expected.to eq ['a', 'x', 'c', 'd', 'e'] }
684
+ its(:index) { is_expected.to eq idx }
685
+ end
686
+
687
+ context "invalid category" do
688
+ it { expect { dv[:x] = 'x' }.to raise_error IndexError }
689
+ end
690
+
691
+ context "invalid positional index" do
692
+ it { expect { dv[30] = 'x'}.to raise_error IndexError }
693
+ end
694
+ end
695
+
696
+ context "numerical index" do
697
+ let (:idx) { DaruLite::CategoricalIndex.new [1, 1, 2, 2, 3] }
698
+ let (:dv) { DaruLite::Vector.new 'a'..'e', index: idx }
699
+
700
+ context "single category" do
701
+ subject { dv }
702
+ before { dv[1] = 'x' }
703
+
704
+ its(:size) { is_expected.to eq 5 }
705
+ its(:to_a) { is_expected.to eq ['x', 'x', 'c', 'd', 'e'] }
706
+ its(:index) { is_expected.to eq idx }
707
+ end
708
+
709
+ context "multiple categories" do
710
+ subject { dv }
711
+ before { dv[1, 2] = 'x' }
712
+
713
+ its(:size) { is_expected.to eq 5 }
714
+ its(:to_a) { is_expected.to eq ['x', 'x', 'x', 'x', 'e'] }
715
+ its(:index) { is_expected.to eq idx }
716
+ end
717
+ end
718
+ end
719
+ end
720
+
721
+ context "#==" do
722
+ subject { vector == other_vector }
723
+
724
+ let(:vector) { DaruLite::Vector.new(data, name:, index:, dtype:) }
725
+ let(:data) { [1, 2, 3, 4, 5] }
726
+ let(:index) { [:yoda, :anakin, :obi, :padme, :r2d2] }
727
+ let(:name) { :yoga }
728
+ let(:other_vector) { DaruLite::Vector.new(other_data, name: other_name, index: other_index, dtype:) }
729
+ let(:other_data) { data }
730
+ let(:other_index) { index }
731
+ let(:other_name) { name }
732
+
733
+ context DaruLite::Index do
734
+
735
+ context 'vectors are identical' do
736
+ it { is_expected.to eq(true) }
737
+ end
738
+
739
+ context 'name is different' do
740
+ let(:other_name) { :yogi }
741
+
742
+ it { is_expected.to eq(true) }
743
+ end
744
+
745
+ context 'data is different' do
746
+ let(:other_data) { [2, 1, 3, 4, 5] }
747
+
748
+ it { is_expected.to eq(false) }
749
+ end
750
+
751
+ context 'data size is different' do
752
+ let(:other_data) { [1, 2, 3, 4, 5, 6] }
753
+ let(:other_index) { [:yoda, :anakin, :obi, :padme, :r2d2, :darth_vader] }
754
+
755
+ it { is_expected.to eq(false) }
756
+ end
757
+
758
+ context 'vector index is different' do
759
+ let(:other_index) { [:anakin, :yoda, :darth_vader, :padme, :r2d2] }
760
+
761
+ it { is_expected.to eq(false) }
762
+ end
763
+ end
764
+
765
+ context DaruLite::MultiIndex do
766
+ let(:tuples) do
767
+ [
768
+ [:a,:one,:bar],
769
+ [:a,:one,:baz],
770
+ [:a,:two,:bar],
771
+ [:a,:two,:baz],
772
+ [:b,:one,:bar],
773
+ [:b,:two,:bar],
774
+ [:b,:two,:baz],
775
+ [:b,:one,:foo],
776
+ [:c,:one,:bar],
777
+ [:c,:one,:baz],
778
+ [:c,:two,:foo],
779
+ [:c,:two,:bar]
780
+ ]
781
+ end
782
+ let(:data) { Array.new(12) { |i| i } }
783
+ let(:index) { DaruLite::MultiIndex.from_tuples(tuples) }
784
+
785
+ context 'vectors are identical' do
786
+ it { is_expected.to eq(true) }
787
+ end
788
+
789
+ context 'name is different' do
790
+ let(:other_name) { :yogi }
791
+
792
+ it { is_expected.to eq(true) }
793
+ end
794
+
795
+ context 'data is different' do
796
+ let(:other_data) { Array.new(12) { |i| i * i } }
797
+
798
+ it { is_expected.to eq(false) }
799
+ end
800
+
801
+ context 'data size is different' do
802
+ let(:other_data) { Array.new(10) { |i| i * i } }
803
+
804
+ it { is_expected.to eq(false) }
805
+ end
806
+
807
+ context 'vector index is different' do
808
+ let(:other_tuples) do
809
+ [
810
+ [:a,:two,:bar],
811
+ [:a,:one,:baz],
812
+ [:a,:two,:bar],
813
+ [:a,:two,:baz],
814
+ [:b,:one,:bar],
815
+ [:b,:two,:bar],
816
+ [:b,:two,:baz],
817
+ [:b,:one,:foo],
818
+ [:c,:one,:bar],
819
+ [:c,:one,:baz],
820
+ [:c,:two,:foo],
821
+ [:c,:two,:bar]
822
+ ]
823
+ end
824
+ let(:other_index) { DaruLite::MultiIndex.from_tuples(other_tuples) }
825
+
826
+ it { is_expected.to eq(false) }
827
+ end
828
+ end
829
+
830
+ context DaruLite::CategoricalIndex do
831
+ let(:index) { DaruLite::CategoricalIndex.new([:yoda, :r2d2, :obi, :padme, :r2d2]) }
832
+
833
+ context 'vectors are identical' do
834
+ it { is_expected.to eq(true) }
835
+ end
836
+
837
+ context 'name is different' do
838
+ let(:other_name) { :yogi }
839
+
840
+ it { is_expected.to eq(true) }
841
+ end
842
+
843
+ context 'data is different' do
844
+ let(:other_data) { [2, 1, 3, 4, 5] }
845
+
846
+ it { is_expected.to eq(false) }
847
+ end
848
+
849
+ context 'data size is different' do
850
+ let(:other_data) { [1, 2, 3, 4, 5, 6] }
851
+ let(:other_index) { [:yoda, :anakin, :obi, :padme, :r2d2, :darth_vader] }
852
+
853
+ it { is_expected.to eq(false) }
854
+ end
855
+
856
+ context 'vector index is different' do
857
+ let(:other_index) { DaruLite::CategoricalIndex.new([:r2d2, :yoda, :obi, :padme, :r2d2]) }
858
+
859
+ it { is_expected.to eq(false) }
860
+ end
861
+ end
862
+ end
863
+
864
+ context "#set_at" do
865
+ context DaruLite::Index do
866
+ let (:idx) { DaruLite::Index.new [1, 0, :c] }
867
+ let (:dv) { DaruLite::Vector.new ['a', 'b', 'c'], index: idx }
868
+
869
+ context "single position" do
870
+ subject { dv }
871
+ before { dv.set_at [1], 'x' }
872
+
873
+ its(:to_a) { is_expected.to eq ['a', 'x', 'c'] }
874
+ end
875
+
876
+ context "multiple positions" do
877
+ subject { dv }
878
+ before { dv.set_at [0, 2], 'x' }
879
+
880
+ its(:to_a) { is_expected.to eq ['x', 'b', 'x'] }
881
+ end
882
+
883
+ context "invalid position" do
884
+ it { expect { dv.set_at [3], 'x' }.to raise_error IndexError }
885
+ end
886
+
887
+ context "invalid positions" do
888
+ it { expect { dv.set_at [2, 3], 'x' }.to raise_error IndexError }
889
+ end
890
+ end
891
+
892
+ context DaruLite::MultiIndex do
893
+ let(:idx) do
894
+ DaruLite::MultiIndex.from_tuples [
895
+ [:a,:one,:bar],
896
+ [:a,:one,:baz],
897
+ [:b,:two,:bar],
898
+ [:a,:two,:baz],
899
+ ]
900
+ end
901
+ let(:dv) { DaruLite::Vector.new 1..4, index: idx }
902
+
903
+ context "single position" do
904
+ subject { dv }
905
+ before { dv.set_at [1], 'x' }
906
+
907
+ its(:to_a) { is_expected.to eq [1, 'x', 3, 4] }
908
+ end
909
+
910
+ context "multiple positions" do
911
+ subject { dv }
912
+ before { dv.set_at [2, 3], 'x' }
913
+
914
+ its(:to_a) { is_expected.to eq [1, 2, 'x', 'x'] }
915
+ end
916
+
917
+ context "invalid position" do
918
+ it { expect { dv.set_at [4], 'x' }.to raise_error IndexError }
919
+ end
920
+
921
+ context "invalid positions" do
922
+ it { expect { dv.set_at [2, 4], 'x' }.to raise_error IndexError }
923
+ end
924
+ end
925
+
926
+ context DaruLite::CategoricalIndex do
927
+ let (:idx) { DaruLite::CategoricalIndex.new [:a, 1, 1, :a, :c] }
928
+ let (:dv) { DaruLite::Vector.new 'a'..'e', index: idx }
929
+
930
+ context "multiple positional indexes" do
931
+ subject { dv }
932
+ before { dv.set_at [0, 1, 2], 'x' }
933
+
934
+ its(:to_a) { is_expected.to eq ['x', 'x', 'x', 'd', 'e'] }
935
+ end
936
+
937
+ context "single positional index" do
938
+ subject { dv }
939
+ before { dv.set_at [1], 'x' }
940
+
941
+ its(:to_a) { is_expected.to eq ['a', 'x', 'c', 'd', 'e'] }
942
+ end
943
+
944
+ context "invalid position" do
945
+ it { expect { dv.set_at [5], 'x' }.to raise_error IndexError }
946
+ end
947
+
948
+ context "invalid positions" do
949
+ it { expect { dv.set_at [2, 5], 'x' }.to raise_error IndexError }
950
+ end
951
+ end
952
+ end
953
+
954
+ context '#head' do
955
+ subject(:vector) do
956
+ DaruLite::Vector.new (1..20).to_a, dtype: dtype
957
+ end
958
+
959
+ it 'takes 10 by default' do
960
+ expect(vector.head).to eq DaruLite::Vector.new (1..10).to_a
961
+ end
962
+
963
+ it 'takes num if provided' do
964
+ expect(vector.head(3)).to eq DaruLite::Vector.new (1..3).to_a
965
+ end
966
+
967
+ it 'does not fail on too large num' do
968
+ expect(vector.head(3000)).to eq vector
969
+ end
970
+ end
971
+
972
+ context '#tail' do
973
+ subject(:vector) do
974
+ DaruLite::Vector.new (1..20).to_a, dtype: dtype
975
+ end
976
+
977
+ it 'takes 10 by default' do
978
+ expect(vector.tail).to eq DaruLite::Vector.new (11..20).to_a, index: (10..19).to_a
979
+ end
980
+
981
+ it 'takes num if provided' do
982
+ expect(vector.tail(3)).to eq DaruLite::Vector.new (18..20).to_a, index: (17..19).to_a
983
+ end
984
+
985
+ it 'does not fail on too large num' do
986
+ expect(vector.tail(3000)).to eq vector
987
+ end
988
+ end
989
+
990
+ context '#last' do
991
+ subject(:vector) do
992
+ DaruLite::Vector.new (1..20).to_a, dtype: dtype
993
+ end
994
+
995
+ it 'takes 1 by default' do
996
+ expect(vector.last).to eq 20
997
+ end
998
+
999
+ it 'takes num if provided' do
1000
+ expect(vector.last(3)).to eq DaruLite::Vector.new (18..20).to_a, index: (17..19).to_a
1001
+ end
1002
+
1003
+ it 'does not fail on too large num' do
1004
+ expect(vector.last(3000)).to eq vector
1005
+ end
1006
+ end
1007
+
1008
+ context "#concat" do
1009
+ before :each do
1010
+ @dv = DaruLite::Vector.new [1,2,3,4,5], name: :yoga,
1011
+ index: [:warwick, :thompson, :jackson, :fender, :esp], dtype: dtype
1012
+ end
1013
+
1014
+ it "concatenates a new element at the end of vector with index" do
1015
+ @dv.concat 6, :ibanez
1016
+
1017
+ expect(@dv.index) .to eq(
1018
+ DaruLite::Index.new([:warwick, :thompson, :jackson, :fender, :esp, :ibanez]))
1019
+ expect(@dv[:ibanez]).to eq(6)
1020
+ expect(@dv[5]) .to eq(6)
1021
+ end
1022
+
1023
+ it "raises error if index not specified" do
1024
+ expect {
1025
+ @dv.concat 6
1026
+ }.to raise_error
1027
+ end
1028
+ end
1029
+
1030
+ context "#delete" do
1031
+ context DaruLite::Index do
1032
+ it "deletes specified value in the vector" do
1033
+ dv = DaruLite::Vector.new [1,2,3,4,5], name: :a, dtype: dtype
1034
+
1035
+ dv.delete 3
1036
+ expect(dv).to eq(
1037
+ DaruLite::Vector.new [1,2,4,5], name: :a, index: [0,1,3,4])
1038
+ end
1039
+ end
1040
+ end
1041
+
1042
+ context "#delete_at" do
1043
+ context DaruLite::Index do
1044
+ before :each do
1045
+ @dv = DaruLite::Vector.new [1,2,3,4,5], name: :a,
1046
+ index: [:one, :two, :three, :four, :five], dtype: dtype
1047
+ end
1048
+
1049
+ it "deletes element of specified index" do
1050
+ @dv.delete_at :one
1051
+
1052
+ expect(@dv).to eq(DaruLite::Vector.new [2,3,4,5], name: :a,
1053
+ index: [:two, :three, :four, :five], dtype: dtype)
1054
+ end
1055
+
1056
+ it "deletes element of specified integer index" do
1057
+ pending
1058
+ @dv.delete_at 2
1059
+
1060
+ expect(@dv).to eq(DaruLite::Vector.new [1,2,4,5], name: :a,
1061
+ index: [:one, :two, :four, :five], dtype: dtype)
1062
+ end
1063
+ end
1064
+ end
1065
+
1066
+ context "#delete_if" do
1067
+ it "deletes elements if block evaluates to true" do
1068
+ v = DaruLite::Vector.new [1,22,33,45,65,32,524,656,123,99,77], dtype: dtype
1069
+ ret = v.delete_if { |d| d % 11 == 0 }
1070
+ expect(ret).to eq(
1071
+ DaruLite::Vector.new([1,45,65,32,524,656,123],
1072
+ index: [0,3,4,5,6,7,8], dtype: dtype))
1073
+ expect(ret.dtype).to eq(dtype)
1074
+ end
1075
+ end
1076
+
1077
+ context "#keep_if" do
1078
+ it "keeps elements if block returns true" do
1079
+ v = DaruLite::Vector.new([1,22,33,45,65,32,524,656,123,99,77], dtype: dtype)
1080
+ ret = v.keep_if { |d| d < 35 }
1081
+
1082
+ expect(ret).to eq(
1083
+ DaruLite::Vector.new([1,22,33,32], index: [0,1,2,5], dtype: dtype))
1084
+ expect(v.dtype).to eq(ret.dtype)
1085
+ end
1086
+ end
1087
+
1088
+ context "#index_of" do
1089
+ context DaruLite::Index do
1090
+ it "returns index of specified value" do
1091
+ dv = DaruLite::Vector.new [1,2,3,4,5], name: :a,
1092
+ index: [:one, :two, :three, :four, :five], dtype: dtype
1093
+
1094
+ expect(dv.index_of(1)).to eq(:one)
1095
+ end
1096
+ end
1097
+
1098
+ context DaruLite::MultiIndex do
1099
+ it "returns tuple of specified value" do
1100
+ mi = DaruLite::MultiIndex.from_tuples([
1101
+ [:a,:two,:bar],
1102
+ [:a,:two,:baz],
1103
+ [:b,:one,:bar],
1104
+ [:b,:two,:bar]
1105
+ ])
1106
+ vector = DaruLite::Vector.new([1,2,3,4], index: mi, dtype: dtype)
1107
+ expect(vector.index_of(3)).to eq([:b,:one,:bar])
1108
+ end
1109
+ end
1110
+ end
1111
+
1112
+ context "#to_df" do
1113
+ let(:dv) { DaruLite::Vector.new(['a','b','c'], name: :my_dv, index: ['alpha', 'beta', 'gamma']) }
1114
+ let(:df) { dv.to_df }
1115
+
1116
+ it 'is a dataframe' do
1117
+ expect(df).to be_a DaruLite::DataFrame
1118
+ end
1119
+
1120
+ it 'converts the vector to a single-vector dataframe' do
1121
+ expect(df[:my_dv]).to eq dv
1122
+ end
1123
+
1124
+ it 'has the same index as the original vector' do
1125
+ expect(df.index).to eq dv.index
1126
+ end
1127
+
1128
+ it 'has the same name as the vector' do
1129
+ expect(df.name).to eq :my_dv
1130
+ end
1131
+ end
1132
+
1133
+ context "#to_h" do
1134
+ context DaruLite::Index do
1135
+ it "returns the vector as a hash" do
1136
+ dv = DaruLite::Vector.new [1,2,3,4,5], name: :a,
1137
+ index: [:one, :two, :three, :four, :five], dtype: dtype
1138
+
1139
+ expect(dv.to_h).to eq({one: 1, two: 2, three: 3, four: 4, five: 5})
1140
+ end
1141
+ end
1142
+
1143
+ context DaruLite::MultiIndex do
1144
+ pending
1145
+ # it "returns vector as a Hash" do
1146
+ # pending
1147
+ # mi = DaruLite::MultiIndex.from_tuples([
1148
+ # [:a,:two,:bar],
1149
+ # [:a,:two,:baz],
1150
+ # [:b,:one,:bar],
1151
+ # [:b,:two,:bar]
1152
+ # ])
1153
+ # vector = DaruLite::Vector.new([1,2,3,4], index: mi, dtype: dtype)
1154
+ # expect(vector.to_h).to eq({
1155
+ # [:a,:two,:bar] => 1,
1156
+ # [:a,:two,:baz] => 2,
1157
+ # [:b,:one,:bar] => 3,
1158
+ # [:b,:two,:bar] => 4
1159
+ # })
1160
+ # end
1161
+ end
1162
+ end
1163
+
1164
+ context "#to_json" do
1165
+ subject(:vector) do
1166
+ DaruLite::Vector.new [1,2,3,4,5], name: :a,
1167
+ index: [:one, :two, :three, :four, :five], dtype: dtype
1168
+ end
1169
+
1170
+ its(:to_json) { is_expected.to eq(vector.to_h.to_json) }
1171
+ end
1172
+
1173
+ context "#to_s" do
1174
+ before do
1175
+ @v = DaruLite::Vector.new ["a", "b"], index: [1, 2]
1176
+ end
1177
+
1178
+ it 'produces a class, size description' do
1179
+ expect(@v.to_s).to eq("#<DaruLite::Vector(2)>")
1180
+ end
1181
+
1182
+ it 'produces a class, name, size description' do
1183
+ @v.name = "Test"
1184
+ expect(@v.to_s).to eq("#<DaruLite::Vector: Test(2)>")
1185
+ end
1186
+
1187
+ it 'produces a class, name, size description when the name is a symbol' do
1188
+ @v.name = :Test
1189
+ expect(@v.to_s).to eq("#<DaruLite::Vector: Test(2)>")
1190
+ end
1191
+ end
1192
+
1193
+ context "#uniq" do
1194
+ before do
1195
+ @v = DaruLite::Vector.new [1, 2, 2, 2.0, 3, 3.0], index:[:a, :b, :c, :d, :e, :f]
1196
+ end
1197
+ it "keeps only unique values" do
1198
+ expect(@v.uniq).to eq(DaruLite::Vector.new [1, 2, 2.0, 3, 3.0], index: [:a, :b, :d, :e, :f])
1199
+ end
1200
+ end
1201
+
1202
+ context "#cast" do
1203
+ ALL_DTYPES.each do |new_dtype|
1204
+ it "casts from #{dtype} to #{new_dtype}" do
1205
+ v = DaruLite::Vector.new [1,2,3,4], dtype: dtype
1206
+ v.cast(dtype: new_dtype)
1207
+ expect(v.dtype).to eq(new_dtype)
1208
+ end
1209
+ end
1210
+ end
1211
+
1212
+ context "#sort" do
1213
+ context DaruLite::Index do
1214
+ before do
1215
+ @dv = DaruLite::Vector.new [33,2,15,332,1], name: :dv, index: [:a, :b, :c, :d, :e]
1216
+ end
1217
+
1218
+ it "sorts the vector with defaults and returns a new vector, preserving indexing" do
1219
+ expect(@dv.sort).to eq(DaruLite::Vector.new([1,2,15,33,332], name: :dv, index: [:e, :b, :c, :a, :d]))
1220
+ end
1221
+
1222
+ it "sorts the vector in descending order" do
1223
+ expect(@dv.sort(ascending: false)).to eq(DaruLite::Vector.new([332,33,15,2,1], name: :dv, index: [:d, :a, :c, :b, :e]))
1224
+ end
1225
+
1226
+ it "accepts a block" do
1227
+ str_dv = DaruLite::Vector.new ["My Jazz Guitar", "Jazz", "My", "Guitar"]
1228
+
1229
+ sorted = str_dv.sort { |a,b| a.length <=> b.length }
1230
+ expect(sorted).to eq(DaruLite::Vector.new(["My", "Jazz", "Guitar", "My Jazz Guitar"], index: [2,1,3,0]))
1231
+ end
1232
+
1233
+ it "places nils near the beginning of the vector when sorting ascendingly" do
1234
+ with_nils = DaruLite::Vector.new [22,4,nil,111,nil,2]
1235
+
1236
+ expect(with_nils.sort).to eq(DaruLite::Vector.new([nil,nil,2,4,22,111], index: [2,4,5,1,0,3]))
1237
+ end if dtype == :array
1238
+
1239
+ it "places nils near the beginning of the vector when sorting descendingly" do
1240
+ with_nils = DaruLite::Vector.new [22,4,nil,111,nil,2]
1241
+
1242
+ expect(with_nils.sort(ascending: false)).to eq(
1243
+ DaruLite::Vector.new [111,22,4,2,nil,nil], index: [3,0,1,5,4,2])
1244
+ end
1245
+
1246
+ it "correctly sorts vector in ascending order with non-numeric data and nils" do
1247
+ non_numeric = DaruLite::Vector.new ['a','b', nil, 'aa', '1234', nil]
1248
+
1249
+ expect(non_numeric.sort(ascending: true)).to eq(
1250
+ DaruLite::Vector.new [nil,nil,'1234','a','aa','b'], index: [2,5,4,0,3,1])
1251
+ end
1252
+
1253
+ it "correctly sorts vector in descending order with non-numeric data and nils" do
1254
+ non_numeric = DaruLite::Vector.new ['a','b', nil, 'aa', '1234', nil]
1255
+
1256
+ expect(non_numeric.sort(ascending: false)).to eq(
1257
+ DaruLite::Vector.new ['b','aa','a','1234',nil,nil], index: [1,3,0,4,5,2])
1258
+ end
1259
+ end
1260
+
1261
+ context DaruLite::MultiIndex do
1262
+ before do
1263
+ mi = DaruLite::MultiIndex.from_tuples([
1264
+ [:a, :one, :foo],
1265
+ [:a, :two, :bar],
1266
+ [:b, :one, :bar],
1267
+ [:b, :two, :baz],
1268
+ [:b, :three, :bar]
1269
+ ])
1270
+ @vector = DaruLite::Vector.new([44,22,111,0,-56], index: mi, name: :unsorted,
1271
+ dtype: dtype)
1272
+ end
1273
+
1274
+ it "sorts vector" do
1275
+ mi_asc = DaruLite::MultiIndex.from_tuples([
1276
+ [:b, :three, :bar],
1277
+ [:b, :two, :baz],
1278
+ [:a, :two, :bar],
1279
+ [:a, :one, :foo],
1280
+ [:b, :one, :bar]
1281
+ ])
1282
+ expect(@vector.sort).to eq(DaruLite::Vector.new([-56,0,22,44,111], index: mi_asc,
1283
+ name: :ascending, dtype: dtype))
1284
+ end
1285
+
1286
+ it "sorts in descending" do
1287
+ mi_dsc = DaruLite::MultiIndex.from_tuples([
1288
+ [:b, :one, :bar],
1289
+ [:a, :one, :foo],
1290
+ [:a, :two, :bar],
1291
+ [:b, :two, :baz],
1292
+ [:b, :three, :bar]
1293
+ ])
1294
+ expect(@vector.sort(ascending: false)).to eq(DaruLite::Vector.new(
1295
+ [111,44,22,0,-56], index: mi_dsc, name: :descending, dtype: dtype))
1296
+ end
1297
+
1298
+ it "sorts using the supplied block" do
1299
+ mi_abs = DaruLite::MultiIndex.from_tuples([
1300
+ [:b, :two, :baz],
1301
+ [:a, :two, :bar],
1302
+ [:a, :one, :foo],
1303
+ [:b, :three, :bar],
1304
+ [:b, :one, :bar]
1305
+ ])
1306
+ expect(@vector.sort { |a,b| a.abs <=> b.abs }).to eq(DaruLite::Vector.new(
1307
+ [0,22,44,-56,111], index: mi_abs, name: :sort_abs, dtype: dtype))
1308
+ end
1309
+ end
1310
+
1311
+ context DaruLite::CategoricalIndex do
1312
+ let(:idx) { DaruLite::CategoricalIndex.new [:a, 1, :a, 1, :c] }
1313
+ let(:dv_numeric) { DaruLite::Vector.new [4, 5, 3, 2, 1], index: idx }
1314
+ let(:dv_string) { DaruLite::Vector.new ['xxxx', 'zzzzz', 'ccc', 'bb', 'a'], index: idx }
1315
+ let(:dv_nil) { DaruLite::Vector.new [3, nil, 2, 1, -1], index: idx }
1316
+
1317
+ context "increasing order" do
1318
+ context "numeric" do
1319
+ subject { dv_numeric.sort }
1320
+
1321
+ its(:size) { is_expected.to eq 5 }
1322
+ its(:to_a) { is_expected.to eq [1, 2, 3, 4, 5] }
1323
+ its(:'index.to_a') { is_expected.to eq [:c, 1, :a, :a, 1] }
1324
+ end
1325
+
1326
+ context "non-numeric" do
1327
+ subject { dv_string.sort }
1328
+
1329
+ its(:size) { is_expected.to eq 5 }
1330
+ its(:to_a) { is_expected.to eq ['a', 'bb', 'ccc', 'xxxx', 'zzzzz'] }
1331
+ its(:'index.to_a') { is_expected.to eq [:c, 1, :a, :a, 1] }
1332
+ end
1333
+
1334
+ context "block" do
1335
+ subject { dv_string.sort { |a, b| a.length <=> b.length } }
1336
+
1337
+ its(:to_a) { is_expected.to eq ['a', 'bb', 'ccc', 'xxxx', 'zzzzz'] }
1338
+ its(:'index.to_a') { is_expected.to eq [:c, 1, :a, :a, 1] }
1339
+ end
1340
+
1341
+ context "nils" do
1342
+ subject { dv_nil.sort }
1343
+
1344
+ its(:to_a) { is_expected.to eq [nil, -1, 1, 2, 3] }
1345
+ its(:'index.to_a') { is_expected.to eq [1, :c, 1, :a, :a] }
1346
+ end
1347
+ end
1348
+
1349
+ context "decreasing order" do
1350
+ context "numeric" do
1351
+ subject { dv_numeric.sort(ascending: false) }
1352
+
1353
+ its(:size) { is_expected.to eq 5 }
1354
+ its(:to_a) { is_expected.to eq [5, 4, 3, 2, 1] }
1355
+ its(:'index.to_a') { is_expected.to eq [1, :a, :a, 1, :c] }
1356
+ end
1357
+
1358
+ context "non-numeric" do
1359
+ subject { dv_string.sort(ascending: false) }
1360
+
1361
+ its(:size) { is_expected.to eq 5 }
1362
+ its(:to_a) { is_expected.to eq ['zzzzz', 'xxxx', 'ccc', 'bb', 'a'] }
1363
+ its(:'index.to_a') { is_expected.to eq [1, :a, :a, 1, :c] }
1364
+ end
1365
+
1366
+ context "block" do
1367
+ subject do
1368
+ dv_string.sort(ascending: false) { |a, b| a.length <=> b.length }
1369
+ end
1370
+
1371
+ its(:to_a) { is_expected.to eq ['zzzzz', 'xxxx', 'ccc', 'bb', 'a'] }
1372
+ its(:'index.to_a') { is_expected.to eq [1, :a, :a, 1, :c] }
1373
+ end
1374
+
1375
+ context "nils" do
1376
+ subject { dv_nil.sort(ascending: false) }
1377
+
1378
+ its(:to_a) { is_expected.to eq [3, 2, 1, -1, nil] }
1379
+ its(:'index.to_a') { is_expected.to eq [:a, :a, 1, :c, 1] }
1380
+ end
1381
+ end
1382
+ end
1383
+ end
1384
+
1385
+ context "#index=" do
1386
+ before do
1387
+ @vector = DaruLite::Vector.new([1,2,3,4,5])
1388
+ end
1389
+
1390
+ it "simply reassigns index" do
1391
+ index = DaruLite::DateTimeIndex.date_range(:start => '2012', :periods => 5)
1392
+ @vector.index = index
1393
+
1394
+ expect(@vector.index.class).to eq(DaruLite::DateTimeIndex)
1395
+ expect(@vector['2012-1-1']).to eq(1)
1396
+ end
1397
+
1398
+ it "accepts an array as index" do
1399
+ @vector.index = [5,4,3,2,1]
1400
+
1401
+ expect(@vector.index.class).to eq(DaruLite::Index)
1402
+ expect(@vector[5]).to eq(1)
1403
+ end
1404
+
1405
+ it "accepts an range as index" do
1406
+ @vector.index = 'a'..'e'
1407
+
1408
+ expect(@vector.index.class).to eq(DaruLite::Index)
1409
+ expect(@vector['a']).to eq(1)
1410
+ end
1411
+
1412
+ it "raises error for index size != vector size" do
1413
+ expect {
1414
+ @vector.index = DaruLite::Index.new([4,2,6])
1415
+ }.to raise_error(ArgumentError, 'Size of supplied index 3 '\
1416
+ 'does not match size of Vector')
1417
+ end
1418
+ end
1419
+
1420
+ context "#reindex!" do
1421
+ before do
1422
+ @vector = DaruLite::Vector.new([1,2,3,4,5])
1423
+ @index = DaruLite::Index.new([3,4,1,0,6])
1424
+ end
1425
+ it "intelligently reindexes" do
1426
+ @vector.reindex!(@index)
1427
+ expect(@vector).to eq(
1428
+ DaruLite::Vector.new([4,5,2,1,nil], index: @index))
1429
+ end
1430
+ end
1431
+
1432
+ context "#reindex" do
1433
+ before do
1434
+ @vector = DaruLite::Vector.new([1,2,3,4,5])
1435
+ @index = DaruLite::Index.new([3,4,1,0,6])
1436
+ end
1437
+ it "intelligently reindexes" do
1438
+ expect(@vector.reindex(@index)).to eq(
1439
+ DaruLite::Vector.new([4,5,2,1,nil], index: @index))
1440
+ end
1441
+ end
1442
+
1443
+ context "#dup" do
1444
+ before do
1445
+ @dv = DaruLite::Vector.new [1,2], name: :yoda, index: [:happy, :lightsaber]
1446
+ end
1447
+
1448
+ it "copies the original data" do
1449
+ expect(@dv.dup.send(:data)).to eq([1,2])
1450
+ end
1451
+
1452
+ it "creates a new data object" do
1453
+ expect(@dv.dup.send(:data).object_id).not_to eq(@dv.send(:data).object_id)
1454
+ end
1455
+
1456
+ it "copies the name" do
1457
+ expect(@dv.dup.name).to eq(:yoda)
1458
+ end
1459
+
1460
+ it "copies the original index" do
1461
+ expect(@dv.dup.index).to eq(DaruLite::Index.new([:happy, :lightsaber]))
1462
+ end
1463
+
1464
+ it "creates a new index object" do
1465
+ expect(@dv.dup.index.object_id).not_to eq(@dv.index.object_id)
1466
+ end
1467
+ end
1468
+
1469
+ context "#collect" do
1470
+ it "returns an Array" do
1471
+ a = @common_all_dtypes.collect { |v| v }
1472
+ expect(a).to eq([5, 5, 5, 5, 5, 6, 6, 7, 8, 9, 10, 1, 2, 3, 4, 11, -99, -99])
1473
+ end
1474
+ end
1475
+
1476
+ context "#map" do
1477
+ it "maps" do
1478
+ a = @common_all_dtypes.map { |v| v }
1479
+ expect(a).to eq([5, 5, 5, 5, 5, 6, 6, 7, 8, 9, 10, 1, 2, 3, 4, 11, -99, -99])
1480
+ end
1481
+ end
1482
+
1483
+ context "#map!" do
1484
+ it "destructively maps" do
1485
+ @common_all_dtypes.map! { |v| v + 1 }
1486
+ expect(@common_all_dtypes).to eq(DaruLite::Vector.new(
1487
+ [6, 6, 6, 6, 6, 7, 7, 8, 9, 10, 11, 2, 3, 4, 5, 12, -98, -98],
1488
+ dtype: dtype))
1489
+ end
1490
+ end
1491
+
1492
+ context "#recode" do
1493
+ it "maps and returns a vector of dtype of self by default" do
1494
+ a = @common_all_dtypes.recode { |v| v == -99 ? 1 : 0 }
1495
+ exp = DaruLite::Vector.new [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1]
1496
+ expect(a).to eq(exp)
1497
+ expect(a.dtype).to eq(:array)
1498
+ end
1499
+ end
1500
+
1501
+ context "#recode!" do
1502
+ before :each do
1503
+ @vector = DaruLite::Vector.new(
1504
+ [5, 5, 5, 5, 5, 6, 6, 7, 8, 9, 10, 1, 2, 3, 4, 11, -99, -99],
1505
+ dtype: dtype, name: :common_all_dtypes)
1506
+ end
1507
+
1508
+ it "destructively maps and returns a vector of dtype of self by default" do
1509
+ @vector.recode! { |v| v == -99 ? 1 : 0 }
1510
+ exp = DaruLite::Vector.new [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1]
1511
+ expect(@vector).to eq(exp)
1512
+ expect(@vector.dtype).to eq(dtype)
1513
+ end
1514
+ end
1515
+
1516
+ context "#verify" do
1517
+ it "returns a hash of invalid data and index of data" do
1518
+ v = DaruLite::Vector.new [1,2,3,4,5,6,-99,35,-100], dtype: dtype
1519
+ h = v.verify { |d| d > 0 }
1520
+ e = { 6 => -99, 8 => -100 }
1521
+ expect(h).to eq(e)
1522
+ end
1523
+ end
1524
+
1525
+ context "#summary" do
1526
+ subject { dv.summary }
1527
+
1528
+ context 'all types' do
1529
+ let(:dv) { DaruLite::Vector.new([1,2,3,4,5], name: 'vector') }
1530
+
1531
+ it { is_expected.to include dv.name }
1532
+
1533
+ it { is_expected.to include "n :#{dv.size}" }
1534
+
1535
+ it { is_expected.to include "non-missing:#{dv.size - dv.count_values(*DaruLite::MISSING_VALUES)}" }
1536
+ end
1537
+
1538
+
1539
+ context "numeric type" do
1540
+ let(:dv) { DaruLite::Vector.new([1,2,5], name: 'numeric') }
1541
+
1542
+ it { is_expected. to eq %Q{
1543
+ |= numeric
1544
+ | n :3
1545
+ | non-missing:3
1546
+ | median: 2
1547
+ | mean: 2.6667
1548
+ | std.dev.: 2.0817
1549
+ | std.err.: 1.2019
1550
+ | skew: 0.2874
1551
+ | kurtosis: -2.3333
1552
+ }.unindent }
1553
+ end
1554
+
1555
+ context "numeric type with missing values" do
1556
+ let(:dv) { DaruLite::Vector.new([1,2,5,nil,Float::NAN], name: 'numeric') }
1557
+
1558
+ it { is_expected.not_to include 'skew' }
1559
+ it { is_expected.not_to include 'kurtosis' }
1560
+ end
1561
+
1562
+ if dtype == :array
1563
+ context "object type" do
1564
+ let(:dv) { DaruLite::Vector.new([1,1,2,2,"string",nil,Float::NAN], name: 'object') }
1565
+
1566
+ if RUBY_VERSION >= '2.2'
1567
+ it { is_expected.to eq %Q{
1568
+ |= object
1569
+ | n :7
1570
+ | non-missing:5
1571
+ | factors: 1,2,string
1572
+ | mode: 1,2
1573
+ | Distribution
1574
+ | string 1 50.00%
1575
+ | NaN 1 50.00%
1576
+ | 1 2 100.00%
1577
+ | 2 2 100.00%
1578
+ }.unindent }
1579
+ else
1580
+ it { is_expected.to eq %Q{
1581
+ |= object
1582
+ | n :7
1583
+ | non-missing:5
1584
+ | factors: 1,2,string
1585
+ | mode: 1,2
1586
+ | Distribution
1587
+ | NaN 1 50.00%
1588
+ | string 1 50.00%
1589
+ | 2 2 100.00%
1590
+ | 1 2 100.00%
1591
+ }.unindent }
1592
+ end
1593
+ end
1594
+ end
1595
+ end
1596
+
1597
+ context "#bootstrap" do
1598
+ it "returns a vector with mean=mu and sd=se" do
1599
+ rng = Distribution::Normal.rng(0, 1)
1600
+ vector =DaruLite::Vector.new_with_size(100, dtype: dtype) { rng.call}
1601
+
1602
+ df = vector.bootstrap([:mean, :sd], 200)
1603
+ se = 1 / Math.sqrt(vector.size)
1604
+ expect(df[:mean].mean).to be_within(0.3).of(0)
1605
+ expect(df[:mean].sd).to be_within(0.02).of(se)
1606
+ end
1607
+ end
1608
+ end
1609
+ end # describe ALL_DTYPES.each
1610
+
1611
+ # -----------------------------------------------------------------------
1612
+ # works with arrays only
1613
+
1614
+ context "#splitted" do
1615
+ it "splits correctly" do
1616
+ a = DaruLite::Vector.new ['a', 'a,b', 'c,d', 'a,d', 'd', 10, nil]
1617
+ expect(a.splitted).to eq([%w(a), %w(a b), %w(c d), %w(a d), %w(d), [10], nil])
1618
+ end
1619
+ end
1620
+
1621
+ context '#is_values' do
1622
+ let(:dv) { DaruLite::Vector.new [10, 11, 10, nil, nil] }
1623
+
1624
+ context 'single value' do
1625
+ subject { dv.is_values 10 }
1626
+ it { is_expected.to be_a DaruLite::Vector }
1627
+ its(:to_a) { is_expected.to eq [true, false, true, false, false] }
1628
+ end
1629
+
1630
+ context 'multiple values' do
1631
+ subject { dv.is_values 10, nil }
1632
+ it { is_expected.to be_a DaruLite::Vector }
1633
+ its(:to_a) { is_expected.to eq [true, false, true, true, true] }
1634
+ end
1635
+ end
1636
+
1637
+ context "#clone_structure" do
1638
+ context DaruLite::Index do
1639
+ before do
1640
+ @vec = DaruLite::Vector.new([1,2,3,4,5], index: [:a,:b,:c,:d,:e])
1641
+ end
1642
+
1643
+ it "clones a vector with its index and fills it with nils" do
1644
+ expect(@vec.clone_structure).to eq(DaruLite::Vector.new([nil,nil,nil,nil,nil], index: [:a,:b,:c,:d,:e]))
1645
+ end
1646
+ end
1647
+
1648
+ context DaruLite::MultiIndex do
1649
+ pending
1650
+ end
1651
+ end
1652
+
1653
+ context '#reject_values'do
1654
+ let(:dv) { DaruLite::Vector.new [1, nil, 3, :a, Float::NAN, nil, Float::NAN, 1],
1655
+ index: 11..18 }
1656
+ context 'reject only nils' do
1657
+ subject { dv.reject_values nil }
1658
+
1659
+ it { is_expected.to be_a DaruLite::Vector }
1660
+ its(:to_a) { is_expected.to eq [1, 3, :a, Float::NAN, Float::NAN, 1] }
1661
+ its(:'index.to_a') { is_expected.to eq [11, 13, 14, 15, 17, 18] }
1662
+ end
1663
+
1664
+ context 'reject only float::NAN' do
1665
+ subject { dv.reject_values Float::NAN }
1666
+
1667
+ it { is_expected.to be_a DaruLite::Vector }
1668
+ its(:to_a) { is_expected.to eq [1, nil, 3, :a, nil, 1] }
1669
+ its(:'index.to_a') { is_expected.to eq [11, 12, 13, 14, 16, 18] }
1670
+ end
1671
+
1672
+ context 'reject both nil and float::NAN' do
1673
+ subject { dv.reject_values nil, Float::NAN }
1674
+
1675
+ it { is_expected.to be_a DaruLite::Vector }
1676
+ its(:to_a) { is_expected.to eq [1, 3, :a, 1] }
1677
+ its(:'index.to_a') { is_expected.to eq [11, 13, 14, 18] }
1678
+ end
1679
+
1680
+ context 'reject any other value' do
1681
+ subject { dv.reject_values 1, 3 }
1682
+
1683
+ it { is_expected.to be_a DaruLite::Vector }
1684
+ its(:to_a) { is_expected.to eq [nil, :a, Float::NAN, nil, Float::NAN] }
1685
+ its(:'index.to_a') { is_expected.to eq [12, 14, 15, 16, 17] }
1686
+ end
1687
+
1688
+ context 'when resultant vector has only one value' do
1689
+ subject { dv.reject_values 1, :a, nil, Float::NAN }
1690
+
1691
+ it { is_expected.to be_a DaruLite::Vector }
1692
+ its(:to_a) { is_expected.to eq [3] }
1693
+ its(:'index.to_a') { is_expected.to eq [13] }
1694
+ end
1695
+
1696
+ context 'when resultant vector has no value' do
1697
+ subject { dv.reject_values 1, 3, :a, nil, Float::NAN, 5 }
1698
+
1699
+ it { is_expected.to be_a DaruLite::Vector }
1700
+ its(:to_a) { is_expected.to eq [] }
1701
+ its(:'index.to_a') { is_expected.to eq [] }
1702
+ end
1703
+
1704
+ context 'test caching' do
1705
+ let(:dv) { DaruLite::Vector.new [nil]*8, index: 11..18}
1706
+ before do
1707
+ dv.reject_values nil
1708
+ [1, nil, 3, :a, Float::NAN, nil, Float::NAN, 1].each_with_index do |v, pos|
1709
+ dv.set_at [pos], v
1710
+ end
1711
+ end
1712
+
1713
+ context 'reject only nils' do
1714
+ subject { dv.reject_values nil }
1715
+
1716
+ it { is_expected.to be_a DaruLite::Vector }
1717
+ its(:to_a) { is_expected.to eq [1, 3, :a, Float::NAN, Float::NAN, 1] }
1718
+ its(:'index.to_a') { is_expected.to eq [11, 13, 14, 15, 17, 18] }
1719
+ end
1720
+
1721
+ context 'reject only float::NAN' do
1722
+ subject { dv.reject_values Float::NAN }
1723
+
1724
+ it { is_expected.to be_a DaruLite::Vector }
1725
+ its(:to_a) { is_expected.to eq [1, nil, 3, :a, nil, 1] }
1726
+ its(:'index.to_a') { is_expected.to eq [11, 12, 13, 14, 16, 18] }
1727
+ end
1728
+
1729
+ context 'reject both nil and float::NAN' do
1730
+ subject { dv.reject_values nil, Float::NAN }
1731
+
1732
+ it { is_expected.to be_a DaruLite::Vector }
1733
+ its(:to_a) { is_expected.to eq [1, 3, :a, 1] }
1734
+ its(:'index.to_a') { is_expected.to eq [11, 13, 14, 18] }
1735
+ end
1736
+
1737
+ context 'reject any other value' do
1738
+ subject { dv.reject_values 1, 3 }
1739
+
1740
+ it { is_expected.to be_a DaruLite::Vector }
1741
+ its(:to_a) { is_expected.to eq [nil, :a, Float::NAN, nil, Float::NAN] }
1742
+ its(:'index.to_a') { is_expected.to eq [12, 14, 15, 16, 17] }
1743
+ end
1744
+ end
1745
+ end
1746
+
1747
+ context '#include_values?' do
1748
+ context 'only nils' do
1749
+ context 'true' do
1750
+ let(:dv) { DaruLite::Vector.new [1, 2, 3, :a, 'Unknown', nil] }
1751
+ it { expect(dv.include_values? nil).to eq true }
1752
+ end
1753
+
1754
+ context 'false' do
1755
+ let(:dv) { DaruLite::Vector.new [1, 2, 3, :a, 'Unknown'] }
1756
+ it { expect(dv.include_values? nil).to eq false }
1757
+ end
1758
+ end
1759
+
1760
+ context 'only Float::NAN' do
1761
+ context 'true' do
1762
+ let(:dv) { DaruLite::Vector.new [1, nil, 2, 3, Float::NAN] }
1763
+ it { expect(dv.include_values? Float::NAN).to eq true }
1764
+ end
1765
+
1766
+ context 'false' do
1767
+ let(:dv) { DaruLite::Vector.new [1, nil, 2, 3] }
1768
+ it { expect(dv.include_values? Float::NAN).to eq false }
1769
+ end
1770
+ end
1771
+
1772
+ context 'both nil and Float::NAN' do
1773
+ context 'true with only nil' do
1774
+ let(:dv) { DaruLite::Vector.new [1, Float::NAN, 2, 3] }
1775
+ it { expect(dv.include_values? nil, Float::NAN).to eq true }
1776
+ end
1777
+
1778
+ context 'true with only Float::NAN' do
1779
+ let(:dv) { DaruLite::Vector.new [1, nil, 2, 3] }
1780
+ it { expect(dv.include_values? nil, Float::NAN).to eq true }
1781
+ end
1782
+
1783
+ context 'false' do
1784
+ let(:dv) { DaruLite::Vector.new [1, 2, 3] }
1785
+ it { expect(dv.include_values? nil, Float::NAN).to eq false }
1786
+ end
1787
+ end
1788
+
1789
+ context 'any other value' do
1790
+ context 'true' do
1791
+ let(:dv) { DaruLite::Vector.new [1, 2, 3, 4, nil] }
1792
+ it { expect(dv.include_values? 1, 2, 3, 5).to eq true }
1793
+ end
1794
+
1795
+ context 'false' do
1796
+ let(:dv) { DaruLite::Vector.new [1, 2, 3, 4, nil] }
1797
+ it { expect(dv.include_values? 5, 6).to eq false }
1798
+ end
1799
+ end
1800
+ end
1801
+
1802
+ context '#count_values' do
1803
+ let(:dv) { DaruLite::Vector.new [1, 2, 3, 1, 2, nil, nil] }
1804
+ it { expect(dv.count_values 1, 2).to eq 4 }
1805
+ it { expect(dv.count_values nil).to eq 2 }
1806
+ it { expect(dv.count_values 3, Float::NAN).to eq 1 }
1807
+ it { expect(dv.count_values 4).to eq 0 }
1808
+ end
1809
+
1810
+ context '#indexes' do
1811
+ context DaruLite::Index do
1812
+ let(:dv) { DaruLite::Vector.new [1, 2, 1, 2, 3, nil, nil, Float::NAN],
1813
+ index: 11..18 }
1814
+
1815
+ subject { dv.indexes 1, 2, nil, Float::NAN }
1816
+ it { is_expected.to be_a Array }
1817
+ it { is_expected.to eq [11, 12, 13, 14, 16, 17, 18] }
1818
+ end
1819
+
1820
+ context DaruLite::MultiIndex do
1821
+ let(:mi) do
1822
+ DaruLite::MultiIndex.from_tuples([
1823
+ ['M', 2000],
1824
+ ['M', 2001],
1825
+ ['M', 2002],
1826
+ ['M', 2003],
1827
+ ['F', 2000],
1828
+ ['F', 2001],
1829
+ ['F', 2002],
1830
+ ['F', 2003]
1831
+ ])
1832
+ end
1833
+ let(:dv) { DaruLite::Vector.new [1, 2, 1, 2, 3, nil, nil, Float::NAN],
1834
+ index: mi }
1835
+
1836
+ subject { dv.indexes 1, 2, Float::NAN }
1837
+ it { is_expected.to be_a Array }
1838
+ it { is_expected.to eq(
1839
+ [
1840
+ ['M', 2000],
1841
+ ['M', 2001],
1842
+ ['M', 2002],
1843
+ ['M', 2003],
1844
+ ['F', 2003]
1845
+ ]) }
1846
+ end
1847
+ end
1848
+
1849
+ context '#replace_values' do
1850
+ subject do
1851
+ DaruLite::Vector.new(
1852
+ [1, 2, 1, 4, nil, Float::NAN, nil, Float::NAN],
1853
+ index: 11..18
1854
+ )
1855
+ end
1856
+
1857
+ context 'replace nils and NaNs' do
1858
+ before { subject.replace_values [nil, Float::NAN], 10 }
1859
+ its(:to_a) { is_expected.to eq [1, 2, 1, 4, 10, 10, 10, 10] }
1860
+ end
1861
+
1862
+ context 'replace arbitrary values' do
1863
+ before { subject.replace_values [1, 2], 10 }
1864
+ its(:to_a) { is_expected.to eq(
1865
+ [10, 10, 10, 4, nil, Float::NAN, nil, Float::NAN]) }
1866
+ end
1867
+
1868
+ context 'works for single value' do
1869
+ before { subject.replace_values nil, 10 }
1870
+ its(:to_a) { is_expected.to eq(
1871
+ [1, 2, 1, 4, 10, Float::NAN, 10, Float::NAN]) }
1872
+ end
1873
+ end
1874
+
1875
+ context "#replace_nils" do
1876
+ it "replaces all nils with the specified value" do
1877
+ vec = DaruLite::Vector.new([1,2,3,nil,nil,4])
1878
+ expect(vec.replace_nils(2)).to eq(DaruLite::Vector.new([1,2,3,2,2,4]))
1879
+ end
1880
+
1881
+ it "replaces all nils with the specified value (bang)" do
1882
+ vec = DaruLite::Vector.new([1,2,3,nil,nil,4]).replace_nils!(2)
1883
+ expect(vec).to eq(DaruLite::Vector.new([1,2,3,2,2,4]))
1884
+ end
1885
+ end
1886
+
1887
+ context '#rolling_fillna!' do
1888
+ subject do
1889
+ DaruLite::Vector.new(
1890
+ [Float::NAN, 2, 1, 4, nil, Float::NAN, 3, nil, Float::NAN]
1891
+ )
1892
+ end
1893
+
1894
+ context 'rolling_fillna! forwards' do
1895
+ before { subject.rolling_fillna!(:forward) }
1896
+ its(:to_a) { is_expected.to eq [0, 2, 1, 4, 4, 4, 3, 3, 3] }
1897
+ end
1898
+
1899
+ context 'rolling_fillna! backwards' do
1900
+ before { subject.rolling_fillna!(direction: :backward) }
1901
+ its(:to_a) { is_expected.to eq [2, 2, 1, 4, 3, 3, 3, 0, 0] }
1902
+ end
1903
+
1904
+ context 'all invalid vector' do
1905
+ subject do
1906
+ DaruLite::Vector.new(
1907
+ [Float::NAN, Float::NAN, Float::NAN, Float::NAN, Float::NAN]
1908
+ )
1909
+ end
1910
+ before { subject.rolling_fillna!(:forward) }
1911
+ its(:to_a) { is_expected.to eq [0, 0, 0, 0, 0] }
1912
+ end
1913
+
1914
+ context 'with non-default index' do
1915
+ subject do
1916
+ DaruLite::Vector.new(
1917
+ [Float::NAN, 2, 1, 4, nil, Float::NAN, 3, nil, Float::NAN],
1918
+ index: %w[a b c d e f g h i]
1919
+ )
1920
+ end
1921
+ before { subject.rolling_fillna!(direction: :backward) }
1922
+ it { is_expected.to eq DaruLite::Vector.new([2, 2, 1, 4, 3, 3, 3, 0, 0], index: %w[a b c d e f g h i]) }
1923
+ end
1924
+ end
1925
+
1926
+ context '#rolling_fillna' do
1927
+ subject do
1928
+ DaruLite::Vector.new(
1929
+ [Float::NAN, 2, 1, 4, nil, Float::NAN, 3, nil, Float::NAN]
1930
+ )
1931
+ end
1932
+
1933
+ context 'rolling_fillna forwards' do
1934
+ it { expect(subject.rolling_fillna(:forward).to_a).to eq [0, 2, 1, 4, 4, 4, 3, 3, 3] }
1935
+ end
1936
+
1937
+ context 'rolling_fillna backwards' do
1938
+ it { expect(subject.rolling_fillna(direction: :backward).to_a).to eq [2, 2, 1, 4, 3, 3, 3, 0, 0] }
1939
+ end
1940
+ end
1941
+
1942
+ context "#type" do
1943
+ before(:each) do
1944
+ @numeric = DaruLite::Vector.new([1,2,3,4,5])
1945
+ @multi = DaruLite::Vector.new([1,2,3,'sameer','d'])
1946
+ @with_nils = DaruLite::Vector.new([1,2,3,4,nil])
1947
+ end
1948
+
1949
+ it "checks numeric data correctly" do
1950
+ expect(@numeric.type).to eq(:numeric)
1951
+ end
1952
+
1953
+ it "checks for multiple types of data" do
1954
+ expect(@multi.type).to eq(:object)
1955
+ end
1956
+
1957
+ it "changes type to object as per assignment" do
1958
+ expect(@numeric.type).to eq(:numeric)
1959
+ @numeric[2] = 'my string'
1960
+ expect(@numeric.type).to eq(:object)
1961
+ end
1962
+
1963
+ it "changes type to numeric as per assignment" do
1964
+ expect(@multi.type).to eq(:object)
1965
+ @multi[3] = 45
1966
+ @multi[4] = 54
1967
+ expect(@multi.type).to eq(:numeric)
1968
+ end
1969
+
1970
+ it "reports numeric if nils with number data" do
1971
+ expect(@with_nils.type).to eq(:numeric)
1972
+ end
1973
+
1974
+ it "stays numeric when nil is reassigned to a number" do
1975
+ @with_nils[4] = 66
1976
+ expect(@with_nils.type).to eq(:numeric)
1977
+ end
1978
+
1979
+ it "changes to :object when nil is reassigned to anything but a number" do
1980
+ @with_nils[4] = 'string'
1981
+ expect(@with_nils.type).to eq(:object)
1982
+ end
1983
+ end
1984
+
1985
+ context "#to_matrix" do
1986
+ before do
1987
+ @vector = DaruLite::Vector.new [1,2,3,4,5,6]
1988
+ end
1989
+
1990
+ it "converts DaruLite::Vector to a horizontal Ruby Matrix" do
1991
+ expect(@vector.to_matrix).to eq(Matrix[[1,2,3,4,5,6]])
1992
+ end
1993
+
1994
+ it "converts DaruLite::Vector to a vertical Ruby Matrix" do
1995
+ expect(@vector.to_matrix(:vertical)).to eq(Matrix.columns([[1,2,3,4,5,6]]))
1996
+ end
1997
+
1998
+ it 'raises on wrong axis' do
1999
+ expect { @vector.to_matrix(:strange) }.to raise_error(ArgumentError)
2000
+ end
2001
+ end
2002
+
2003
+ context "#only_numerics" do
2004
+ it "returns only numerical or missing data" do
2005
+ v = DaruLite::Vector.new([1,2,nil,3,4,'s','a',nil])
2006
+ expect(v.only_numerics).to eq(DaruLite::Vector.new([1,2,nil,3,4,nil],
2007
+ index: [0,1,2,3,4,7]))
2008
+ end
2009
+ end
2010
+
2011
+ context "#split_by_separator" do
2012
+ def expect_correct_tokens hash
2013
+ expect(hash['a'].to_a).to eq([1, 1, 0, 1, 0, nil])
2014
+ expect(hash['b'].to_a).to eq([0, 1, 0, 0, 0, nil])
2015
+ expect(hash['c'].to_a).to eq([0, 0, 1, 0, 0, nil])
2016
+ expect(hash['d'].to_a).to eq([0, 0, 1, 1, 0, nil])
2017
+ expect(hash[10].to_a).to eq([0, 0, 0, 0, 1, nil])
2018
+ end
2019
+
2020
+ before do
2021
+ @a = DaruLite::Vector.new ['a', 'a,b', 'c,d', 'a,d', 10, nil]
2022
+ @b = @a.split_by_separator(',')
2023
+ end
2024
+
2025
+ it "returns a Hash" do
2026
+ expect(@b.class).to eq(Hash)
2027
+ end
2028
+
2029
+ it "returned Hash has keys with with different values of @a" do
2030
+ expect(@b.keys).to eq(['a', 'b', 'c', 'd', 10])
2031
+ end
2032
+
2033
+ it "returns a Hash, whose values are DaruLite::Vector" do
2034
+ @b.each_key do |key|
2035
+ expect(@b[key].class).to eq(DaruLite::Vector)
2036
+ end
2037
+ end
2038
+
2039
+ it "ensures that hash values are n times the tokens appears" do
2040
+ expect_correct_tokens @b
2041
+ end
2042
+
2043
+ it "gives the same values using a different separator" do
2044
+ a = DaruLite::Vector.new ['a', 'a*b', 'c*d', 'a*d', 10, nil]
2045
+ b = a.split_by_separator '*'
2046
+ expect_correct_tokens b
2047
+ end
2048
+ end
2049
+
2050
+ context "#split_by_separator_freq" do
2051
+ it "returns the number of ocurrences of tokens" do
2052
+ a = DaruLite::Vector.new ['a', 'a,b', 'c,d', 'a,d', 10, nil]
2053
+ expect(a.split_by_separator_freq).to eq(
2054
+ { 'a' => 3, 'b' => 1, 'c' => 1, 'd' => 2, 10 => 1 })
2055
+ end
2056
+ end
2057
+
2058
+ context "#reset_index!" do
2059
+ it "resets any index to a numerical serialized index" do
2060
+ v = DaruLite::Vector.new([1,2,3,4,5,nil,nil,4,nil])
2061
+ r = v.reject_values(*DaruLite::MISSING_VALUES).reset_index!
2062
+ expect(r).to eq(DaruLite::Vector.new([1,2,3,4,5,4]))
2063
+ expect(r.index).to eq(DaruLite::Index.new([0,1,2,3,4,5]))
2064
+
2065
+ indexed = DaruLite::Vector.new([1,2,3,4,5], index: [:a, :b, :c, :d, :e])
2066
+ expect(indexed.reset_index!.index).to eq(DaruLite::Index.new([0,1,2,3,4]))
2067
+ end
2068
+ end
2069
+
2070
+ context "#rename" do
2071
+ before :each do
2072
+ @v = DaruLite::Vector.new [1,2,3,4,5,5], name: :this_vector
2073
+ end
2074
+
2075
+ it "assings name" do
2076
+ @v.rename :that_vector
2077
+ expect(@v.name).to eq(:that_vector)
2078
+ end
2079
+
2080
+ it "stores name as a symbol" do
2081
+ @v.rename "This is a vector"
2082
+ expect(@v.name).to eq("This is a vector")
2083
+ end
2084
+
2085
+ it "returns vector" do
2086
+ expect(@v.rename 'hello').to be_a DaruLite::Vector
2087
+ end
2088
+ end
2089
+
2090
+ context "#any?" do
2091
+ before do
2092
+ @v = DaruLite::Vector.new([1,2,3,4,5])
2093
+ end
2094
+
2095
+ it "returns true if block returns true for any one of the elements" do
2096
+ expect(@v.any?{ |e| e == 1 }).to eq(true)
2097
+ end
2098
+
2099
+ it "returns false if block is false for all elements" do
2100
+ expect(@v.any?{ |e| e > 10 }).to eq(false)
2101
+ end
2102
+ end
2103
+
2104
+ context "#all?" do
2105
+ before do
2106
+ @v = DaruLite::Vector.new([1,2,3,4,5])
2107
+ end
2108
+
2109
+ it "returns true if block is true for all elements" do
2110
+ expect(@v.all? { |e| e < 6 }).to eq(true)
2111
+ end
2112
+
2113
+ it "returns false if block is false for any one element" do
2114
+ expect(@v.all? { |e| e == 2 }).to eq(false)
2115
+ end
2116
+ end
2117
+
2118
+ context "#detach_index" do
2119
+ it "creates a DataFrame with first Vector as index and second as values of the Vector" do
2120
+ v = DaruLite::Vector.new([1,2,3,4,5,6],
2121
+ index: ['a', 'b', 'c', 'd', 'e', 'f'], name: :values)
2122
+ expect(v.detach_index).to eq(DaruLite::DataFrame.new({
2123
+ index: ['a', 'b', 'c', 'd', 'e', 'f'],
2124
+ values: [1,2,3,4,5,6]
2125
+ }))
2126
+ end
2127
+ end
2128
+
2129
+ describe '#lag' do
2130
+ let(:source) { DaruLite::Vector.new(1..5) }
2131
+
2132
+ context 'by default' do
2133
+ subject { source.lag }
2134
+ it { is_expected.to eq DaruLite::Vector.new([nil, 1, 2, 3, 4]) }
2135
+ end
2136
+
2137
+ subject { source.lag(amount) }
2138
+
2139
+ context '0' do
2140
+ let(:amount) { 0 }
2141
+ it { is_expected.to eq DaruLite::Vector.new([1, 2, 3, 4, 5]) }
2142
+ end
2143
+
2144
+ context 'same as vector size' do
2145
+ let(:amount) { source.size }
2146
+ it { is_expected.to eq DaruLite::Vector.new([nil]*source.size) }
2147
+ end
2148
+
2149
+ context 'same as vector -ve size' do
2150
+ let(:amount) { -source.size }
2151
+ it { is_expected.to eq DaruLite::Vector.new([nil]*source.size) }
2152
+ end
2153
+
2154
+ context 'positive' do
2155
+ let(:amount) { 2 }
2156
+ it { is_expected.to eq DaruLite::Vector.new([nil, nil, 1, 2, 3]) }
2157
+ end
2158
+
2159
+ context 'negative' do
2160
+ let(:amount) { -1 }
2161
+ it { is_expected.to eq DaruLite::Vector.new([2, 3, 4, 5, nil]) }
2162
+ end
2163
+
2164
+ context 'large positive' do
2165
+ let(:amount) { source.size + 100 }
2166
+ it { is_expected.to eq DaruLite::Vector.new([nil]*source.size) }
2167
+ end
2168
+
2169
+ context 'large negative' do
2170
+ let(:amount) { -(source.size + 100) }
2171
+ it { is_expected.to eq DaruLite::Vector.new([nil]*source.size) }
2172
+ end
2173
+
2174
+ end
2175
+
2176
+ context "#group_by" do
2177
+ let(:dv) { DaruLite::Vector.new [:a, :b, :a, :b, :c] }
2178
+
2179
+ context 'vector not specified' do
2180
+ subject { dv.group_by }
2181
+
2182
+ it { is_expected.to be_a DaruLite::Core::GroupBy }
2183
+ its(:'groups.size') { is_expected.to eq 3 }
2184
+ its(:groups) { is_expected.to eq({[:a]=>[0, 2], [:b]=>[1, 3], [:c]=>[4]}) }
2185
+ end
2186
+
2187
+ context 'vector name specified' do
2188
+ before { dv.name = :hello }
2189
+ subject { dv.group_by :hello }
2190
+
2191
+ it { is_expected.to be_a DaruLite::Core::GroupBy }
2192
+ its(:'groups.size') { is_expected.to eq 3 }
2193
+ its(:groups) { is_expected.to eq({[:a]=>[0, 2], [:b]=>[1, 3], [:c]=>[4]}) }
2194
+ end
2195
+
2196
+ context 'vector name invalid' do
2197
+ before { dv.name = :hello }
2198
+ it { expect { dv.group_by :abc }.to raise_error }
2199
+ end
2200
+ end
2201
+
2202
+ context '#match' do
2203
+ subject { dv.match(regexp) }
2204
+
2205
+ context 'returns matching array for a given regexp' do
2206
+ let(:dv) { DaruLite::Vector.new ['3 days', '5 weeks', '2 weeks'] }
2207
+ let(:regexp) { /weeks/ }
2208
+
2209
+ it { is_expected.to eq([false, true, true]) }
2210
+ end
2211
+ end
2212
+
2213
+ context '#method_missing' do
2214
+ context 'getting' do
2215
+ subject(:vector) { DaruLite::Vector.new [1,2,3], index: [:a, :b, :c] }
2216
+
2217
+ it 'returns value for existing index' do
2218
+ expect(vector.a).to eq 1
2219
+ end
2220
+
2221
+ it 'raises on getting non-existent index' do
2222
+ expect { vector.d }.to raise_error NoMethodError
2223
+ end
2224
+
2225
+ it 'sets existing index' do
2226
+ vector.a = 5
2227
+ expect(vector[:a]).to eq 5
2228
+ end
2229
+
2230
+ it 'raises on non-existent index setting' do
2231
+ # FIXME: inconsistency between IndexError here and NoMethodError on getting - zverok
2232
+ expect { vector.d = 5 }.to raise_error IndexError
2233
+ end
2234
+ end
2235
+ end
2236
+
2237
+ context "#sort_by_index" do
2238
+ let(:asc) { vector.sort_by_index }
2239
+ let(:desc) { vector.sort_by_index(ascending: false) }
2240
+
2241
+ context 'numeric vector' do
2242
+ let(:vector) { DaruLite::Vector.new [11, 13, 12], index: [23, 21, 22] }
2243
+ specify { expect(asc.to_a).to eq [13, 12, 11] }
2244
+ specify { expect(desc.to_a).to eq [11, 12, 13] }
2245
+ end
2246
+
2247
+ context 'mix variable type index' do
2248
+ let(:vector) { DaruLite::Vector.new [11, Float::NAN, nil],
2249
+ index: [21, 23, 22] }
2250
+ specify { expect(asc.to_a).to eq [11, nil, Float::NAN] }
2251
+ specify { expect(desc.to_a).to eq [Float::NAN, nil, 11] }
2252
+ end
2253
+ end
2254
+
2255
+ context '#db_type' do
2256
+ it 'is DATE for vector with any date in it' do
2257
+ # FIXME: is it sane?.. - zverok
2258
+ expect(DaruLite::Vector.new(['2016-03-01', 'foo', 4]).db_type).to eq 'DATE'
2259
+ end
2260
+
2261
+ it 'is INTEGER for digits-only values' do
2262
+ expect(DaruLite::Vector.new(['123', 456, 789]).db_type).to eq 'INTEGER'
2263
+ end
2264
+
2265
+ it 'is DOUBLE for digits-and-point values' do
2266
+ expect(DaruLite::Vector.new(['123.4', 456, 789e-10]).db_type).to eq 'DOUBLE'
2267
+ end
2268
+
2269
+ it 'is VARCHAR for everyting else' do
2270
+ expect(DaruLite::Vector.new(['123 and stuff', 456, 789e-10]).db_type).to eq 'VARCHAR (255)'
2271
+ end
2272
+ end
2273
+
2274
+ context 'on wrong dtypes' do
2275
+ it 'should not accept mdarray' do
2276
+ expect { DaruLite::Vector.new([], dtype: :mdarray) }.to raise_error(NotImplementedError)
2277
+ end
2278
+
2279
+ it 'should not accept anything else' do
2280
+ expect { DaruLite::Vector.new([], dtype: :kittens) }.to raise_error(ArgumentError)
2281
+ end
2282
+ end
2283
+
2284
+ context '#where clause when Nan, nil data value is present' do
2285
+ let(:v) { DaruLite::Vector.new([1,2,3,Float::NAN, nil]) }
2286
+
2287
+ it 'missing/undefined data in Vector/DataFrame' do
2288
+ expect(v.where(v.lt(4))).to eq(DaruLite::Vector.new([1,2,3]))
2289
+ expect(v.where(v.lt(3))).to eq(DaruLite::Vector.new([1,2]))
2290
+ expect(v.where(v.lt(2))).to eq(DaruLite::Vector.new([1]))
2291
+ end
2292
+ end
2293
+ end if mri?