daru_lite 0.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +7 -0
- data/.github/ISSUE_TEMPLATE.md +18 -0
- data/.github/workflows/ci.yml +33 -0
- data/.gitignore +10 -0
- data/.rspec +2 -0
- data/.rubocop.yml +27 -0
- data/.rubocop_todo.yml +137 -0
- data/CONTRIBUTING.md +47 -0
- data/Gemfile +2 -0
- data/History.md +4 -0
- data/LICENSE +24 -0
- data/README.md +218 -0
- data/Rakefile +69 -0
- data/ReleasePolicy.md +20 -0
- data/benchmarks/TradeoffData.csv +65 -0
- data/benchmarks/csv_reading.rb +22 -0
- data/benchmarks/dataframe_creation.rb +39 -0
- data/benchmarks/db_loading.rb +34 -0
- data/benchmarks/duplicating.rb +45 -0
- data/benchmarks/group_by.rb +32 -0
- data/benchmarks/joining.rb +52 -0
- data/benchmarks/row_access.rb +41 -0
- data/benchmarks/row_assign.rb +36 -0
- data/benchmarks/sorting.rb +51 -0
- data/benchmarks/statistics.rb +28 -0
- data/benchmarks/vector_access.rb +31 -0
- data/benchmarks/vector_assign.rb +42 -0
- data/benchmarks/where_clause.rb +48 -0
- data/benchmarks/where_vs_filter.rb +28 -0
- data/daru_lite.gemspec +55 -0
- data/images/README.md +5 -0
- data/images/con0.png +0 -0
- data/images/con1.png +0 -0
- data/images/init0.png +0 -0
- data/images/init1.png +0 -0
- data/images/man0.png +0 -0
- data/images/man1.png +0 -0
- data/images/man2.png +0 -0
- data/images/man3.png +0 -0
- data/images/man4.png +0 -0
- data/images/man5.png +0 -0
- data/images/man6.png +0 -0
- data/lib/daru_lite/accessors/array_wrapper.rb +109 -0
- data/lib/daru_lite/accessors/dataframe_by_row.rb +25 -0
- data/lib/daru_lite/accessors/mdarray_wrapper.rb +7 -0
- data/lib/daru_lite/category.rb +929 -0
- data/lib/daru_lite/configuration.rb +34 -0
- data/lib/daru_lite/core/group_by.rb +403 -0
- data/lib/daru_lite/core/merge.rb +270 -0
- data/lib/daru_lite/core/query.rb +109 -0
- data/lib/daru_lite/dataframe.rb +3080 -0
- data/lib/daru_lite/date_time/index.rb +569 -0
- data/lib/daru_lite/date_time/offsets.rb +397 -0
- data/lib/daru_lite/exceptions.rb +2 -0
- data/lib/daru_lite/extensions/which_dsl.rb +53 -0
- data/lib/daru_lite/formatters/table.rb +52 -0
- data/lib/daru_lite/helpers/array.rb +53 -0
- data/lib/daru_lite/index/categorical_index.rb +201 -0
- data/lib/daru_lite/index/index.rb +374 -0
- data/lib/daru_lite/index/multi_index.rb +374 -0
- data/lib/daru_lite/io/csv/converters.rb +21 -0
- data/lib/daru_lite/io/io.rb +294 -0
- data/lib/daru_lite/io/sql_data_source.rb +97 -0
- data/lib/daru_lite/iruby/helpers.rb +38 -0
- data/lib/daru_lite/iruby/templates/dataframe.html.erb +5 -0
- data/lib/daru_lite/iruby/templates/dataframe_mi.html.erb +5 -0
- data/lib/daru_lite/iruby/templates/dataframe_mi_tbody.html.erb +35 -0
- data/lib/daru_lite/iruby/templates/dataframe_mi_thead.html.erb +21 -0
- data/lib/daru_lite/iruby/templates/dataframe_tbody.html.erb +28 -0
- data/lib/daru_lite/iruby/templates/dataframe_thead.html.erb +21 -0
- data/lib/daru_lite/iruby/templates/multi_index.html.erb +12 -0
- data/lib/daru_lite/iruby/templates/vector.html.erb +5 -0
- data/lib/daru_lite/iruby/templates/vector_mi.html.erb +5 -0
- data/lib/daru_lite/iruby/templates/vector_mi_tbody.html.erb +26 -0
- data/lib/daru_lite/iruby/templates/vector_mi_thead.html.erb +8 -0
- data/lib/daru_lite/iruby/templates/vector_tbody.html.erb +17 -0
- data/lib/daru_lite/iruby/templates/vector_thead.html.erb +8 -0
- data/lib/daru_lite/maths/arithmetic/dataframe.rb +91 -0
- data/lib/daru_lite/maths/arithmetic/vector.rb +117 -0
- data/lib/daru_lite/maths/statistics/dataframe.rb +202 -0
- data/lib/daru_lite/maths/statistics/vector.rb +1019 -0
- data/lib/daru_lite/monkeys.rb +56 -0
- data/lib/daru_lite/vector.rb +1678 -0
- data/lib/daru_lite/version.rb +3 -0
- data/lib/daru_lite.rb +99 -0
- data/profile/_base.rb +23 -0
- data/profile/df_to_a.rb +10 -0
- data/profile/filter.rb +13 -0
- data/profile/joining.rb +13 -0
- data/profile/sorting.rb +12 -0
- data/profile/vector_each_with_index.rb +9 -0
- data/profile/vector_new.rb +9 -0
- data/spec/accessors/array_wrapper_spec.rb +3 -0
- data/spec/category_spec.rb +1741 -0
- data/spec/core/group_by_spec.rb +655 -0
- data/spec/core/merge_spec.rb +179 -0
- data/spec/core/query_spec.rb +347 -0
- data/spec/daru_lite_spec.rb +22 -0
- data/spec/dataframe_spec.rb +4330 -0
- data/spec/date_time/data_spec.rb +197 -0
- data/spec/date_time/date_time_index_helper_spec.rb +72 -0
- data/spec/date_time/index_spec.rb +588 -0
- data/spec/date_time/offsets_spec.rb +465 -0
- data/spec/extensions/which_dsl_spec.rb +38 -0
- data/spec/fixtures/bank2.dat +200 -0
- data/spec/fixtures/boolean_converter_test.csv +5 -0
- data/spec/fixtures/countries.json +7794 -0
- data/spec/fixtures/duplicates.csv +32 -0
- data/spec/fixtures/eciresults.html +394 -0
- data/spec/fixtures/empties.dat +2 -0
- data/spec/fixtures/empty_rows_test.csv +17 -0
- data/spec/fixtures/macau.html +3691 -0
- data/spec/fixtures/macd_data.csv +150 -0
- data/spec/fixtures/matrix_test.csv +100 -0
- data/spec/fixtures/moneycontrol.html +6812 -0
- data/spec/fixtures/music_data.tsv +2501 -0
- data/spec/fixtures/repeated_fields.csv +7 -0
- data/spec/fixtures/sales-funnel.csv +18 -0
- data/spec/fixtures/scientific_notation.csv +4 -0
- data/spec/fixtures/string_converter_test.csv +5 -0
- data/spec/fixtures/strings.dat +2 -0
- data/spec/fixtures/test_xls.xls +0 -0
- data/spec/fixtures/test_xls_2.xls +0 -0
- data/spec/fixtures/url_test.txt~ +0 -0
- data/spec/fixtures/valid_markup.html +62 -0
- data/spec/fixtures/wiki_climate.html +1243 -0
- data/spec/fixtures/wiki_table_info.html +631 -0
- data/spec/formatters/table_formatter_spec.rb +137 -0
- data/spec/helpers_spec.rb +8 -0
- data/spec/index/categorical_index_spec.rb +170 -0
- data/spec/index/index_spec.rb +417 -0
- data/spec/index/multi_index_spec.rb +680 -0
- data/spec/io/io_spec.rb +373 -0
- data/spec/io/sql_data_source_spec.rb +56 -0
- data/spec/iruby/dataframe_spec.rb +170 -0
- data/spec/iruby/helpers_spec.rb +49 -0
- data/spec/iruby/multi_index_spec.rb +37 -0
- data/spec/iruby/vector_spec.rb +105 -0
- data/spec/maths/arithmetic/dataframe_spec.rb +148 -0
- data/spec/maths/arithmetic/vector_spec.rb +165 -0
- data/spec/maths/statistics/dataframe_spec.rb +178 -0
- data/spec/maths/statistics/vector_spec.rb +756 -0
- data/spec/monkeys_spec.rb +42 -0
- data/spec/shared/vector_display_spec.rb +213 -0
- data/spec/spec_helper.rb +87 -0
- data/spec/support/database_helper.rb +30 -0
- data/spec/support/matchers.rb +5 -0
- data/spec/vector_spec.rb +2293 -0
- metadata +571 -0
data/spec/vector_spec.rb
ADDED
|
@@ -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?
|