daru_lite 0.1.2 → 0.2.0
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 +4 -4
- data/.github/dependabot.yml +11 -0
- data/.github/workflows/ci.yml +2 -2
- data/.rubocop.yml +2 -2
- data/benchmarks/db_loading.rb +0 -1
- data/daru_lite.gemspec +10 -12
- data/daru_lite_test-shm +0 -0
- data/daru_lite_test-wal +0 -0
- data/lib/daru_lite/accessors/array_wrapper.rb +4 -4
- data/lib/daru_lite/core/merge.rb +8 -8
- data/lib/daru_lite/data_frame/calculatable.rb +2 -2
- data/lib/daru_lite/data_frame/filterable.rb +4 -4
- data/lib/daru_lite/data_frame/i_o_able.rb +17 -14
- data/lib/daru_lite/data_frame/iterable.rb +11 -11
- data/lib/daru_lite/data_frame/queryable.rb +5 -5
- data/lib/daru_lite/dataframe.rb +16 -14
- data/lib/daru_lite/date_time/index.rb +10 -10
- data/lib/daru_lite/extensions/which_dsl.rb +2 -2
- data/lib/daru_lite/index/index.rb +4 -4
- data/lib/daru_lite/index/multi_index.rb +13 -4
- data/lib/daru_lite/io/io.rb +10 -9
- data/lib/daru_lite/io/sql_data_source.rb +7 -24
- data/lib/daru_lite/maths/statistics/dataframe.rb +2 -2
- data/lib/daru_lite/maths/statistics/vector.rb +16 -16
- data/lib/daru_lite/vector/aggregatable.rb +2 -2
- data/lib/daru_lite/vector/filterable.rb +2 -2
- data/lib/daru_lite/vector/queryable.rb +4 -4
- data/lib/daru_lite/vector/sortable.rb +4 -4
- data/lib/daru_lite/vector.rb +4 -6
- data/lib/daru_lite/version.rb +1 -1
- data/spec/data_frame/filterable_example.rb +174 -15
- data/spec/index/categorical_index_spec.rb +27 -8
- data/spec/index/index_spec.rb +16 -3
- data/spec/index/multi_index_spec.rb +85 -76
- data/spec/io/io_spec.rb +0 -16
- data/spec/io/sql_data_source_spec.rb +0 -8
- data/spec/spec_helper.rb +1 -1
- data/spec/support/database_helper.rb +0 -1
- metadata +30 -65
@@ -16,24 +16,6 @@ module DaruLite
|
|
16
16
|
end
|
17
17
|
end
|
18
18
|
|
19
|
-
# Private adapter class for DBI::DatabaseHandle
|
20
|
-
# @private
|
21
|
-
class DbiAdapter < Adapter
|
22
|
-
private
|
23
|
-
|
24
|
-
def column_names
|
25
|
-
result.column_names
|
26
|
-
end
|
27
|
-
|
28
|
-
def rows
|
29
|
-
result.to_a.map(&:to_a)
|
30
|
-
end
|
31
|
-
|
32
|
-
def result
|
33
|
-
@result ||= @conn.execute(@query)
|
34
|
-
end
|
35
|
-
end
|
36
|
-
|
37
19
|
# Private adapter class for connections of ActiveRecord
|
38
20
|
# @private
|
39
21
|
class ActiveRecordConnectionAdapter < Adapter
|
@@ -52,7 +34,6 @@ module DaruLite
|
|
52
34
|
end
|
53
35
|
end
|
54
36
|
|
55
|
-
private_constant :DbiAdapter
|
56
37
|
private_constant :ActiveRecordConnectionAdapter
|
57
38
|
|
58
39
|
def self.make_dataframe(db, query)
|
@@ -76,8 +57,6 @@ module DaruLite
|
|
76
57
|
db = attempt_sqlite3_connection(db) if db.is_a?(String) && Pathname(db).exist?
|
77
58
|
|
78
59
|
case db
|
79
|
-
when DBI::DatabaseHandle
|
80
|
-
DbiAdapter.new(db, query)
|
81
60
|
when ActiveRecord::ConnectionAdapters::AbstractAdapter
|
82
61
|
ActiveRecordConnectionAdapter.new(db, query)
|
83
62
|
else
|
@@ -86,11 +65,15 @@ module DaruLite
|
|
86
65
|
end
|
87
66
|
|
88
67
|
def attempt_sqlite3_connection(db)
|
89
|
-
|
90
|
-
|
68
|
+
ActiveRecord::Base.establish_connection(
|
69
|
+
adapter: 'sqlite3',
|
70
|
+
database: db
|
71
|
+
)
|
72
|
+
ActiveRecord::Base.connection.tap(&:verify!)
|
73
|
+
rescue ActiveRecord::StatementInvalid
|
91
74
|
raise ArgumentError, "Expected #{db} to point to a SQLite3 database"
|
92
75
|
rescue NameError
|
93
|
-
raise NameError, "In order to establish a connection to #{db}, please require '
|
76
|
+
raise NameError, "In order to establish a connection to #{db}, please require 'ActiveRecord'"
|
94
77
|
end
|
95
78
|
end
|
96
79
|
end
|
@@ -165,10 +165,10 @@ module DaruLite
|
|
165
165
|
|
166
166
|
private
|
167
167
|
|
168
|
-
def apply_method_to_numerics(method, *
|
168
|
+
def apply_method_to_numerics(method, *)
|
169
169
|
numerics = @vectors.to_a.map { |n| [n, @data[@vectors[n]]] }
|
170
170
|
.select { |_n, v| v.numeric? }
|
171
|
-
computed = numerics.map { |_n, v| v.send(method, *
|
171
|
+
computed = numerics.map { |_n, v| v.send(method, *) }
|
172
172
|
|
173
173
|
DaruLite::DataFrame.new(computed, index: @index, order: numerics.map(&:first), clone: false)
|
174
174
|
end
|
@@ -89,8 +89,8 @@ module DaruLite
|
|
89
89
|
#
|
90
90
|
# dv.max(2) { |a,b| a.size <=> b.size }
|
91
91
|
# #=> ["Jon Starkgaryen","Daenerys"]
|
92
|
-
def max(size = nil, &
|
93
|
-
reject_values(*DaruLite::MISSING_VALUES).to_a.max(size, &
|
92
|
+
def max(size = nil, &)
|
93
|
+
reject_values(*DaruLite::MISSING_VALUES).to_a.max(size, &)
|
94
94
|
end
|
95
95
|
|
96
96
|
# Returns the maximum value(s) present in the vector, with a compulsory object block.
|
@@ -134,8 +134,8 @@ module DaruLite
|
|
134
134
|
#
|
135
135
|
# dv.min(2) { |a,b| a.size <=> b.size }
|
136
136
|
# #=> ["Tyrion","Daenerys"]
|
137
|
-
def min(size = nil, &
|
138
|
-
reject_values(*DaruLite::MISSING_VALUES).to_a.min(size, &
|
137
|
+
def min(size = nil, &)
|
138
|
+
reject_values(*DaruLite::MISSING_VALUES).to_a.min(size, &)
|
139
139
|
end
|
140
140
|
|
141
141
|
# Returns the minimum value(s) present in the vector, with a compulsory object block.
|
@@ -179,9 +179,9 @@ module DaruLite
|
|
179
179
|
#
|
180
180
|
# dv.max(2) { |a,b| a.size <=> b.size }
|
181
181
|
# #=> ["Jon Starkgaryen","Daenerys"]
|
182
|
-
def max(size = nil, &
|
182
|
+
def max(size = nil, &)
|
183
183
|
range = size.nil? ? 0 : (0..size - 1)
|
184
|
-
reject_values(*DaruLite::MISSING_VALUES).to_a.sort(&
|
184
|
+
reject_values(*DaruLite::MISSING_VALUES).to_a.sort(&).reverse[range]
|
185
185
|
end
|
186
186
|
|
187
187
|
# Returns the maximum value(s) present in the vector, with a compulsory object block.
|
@@ -225,9 +225,9 @@ module DaruLite
|
|
225
225
|
#
|
226
226
|
# dv.min(2) { |a,b| a.size <=> b.size }
|
227
227
|
# #=> ["Tyrion","Daenerys"]
|
228
|
-
def min(size = nil, &
|
228
|
+
def min(size = nil, &)
|
229
229
|
range = size.nil? ? 0 : (0..size - 1)
|
230
|
-
reject_values(*DaruLite::MISSING_VALUES).to_a.sort(&
|
230
|
+
reject_values(*DaruLite::MISSING_VALUES).to_a.sort(&)[range]
|
231
231
|
end
|
232
232
|
|
233
233
|
# Returns the minimum value(s) present in the vector, with a compulsory object block.
|
@@ -276,8 +276,8 @@ module DaruLite
|
|
276
276
|
#
|
277
277
|
# dv.index_of_max(2) { |a,b| a.size <=> b.size }
|
278
278
|
# #=> [:j, :d]
|
279
|
-
def index_of_max(size = nil, &
|
280
|
-
vals = max(size, &
|
279
|
+
def index_of_max(size = nil, &)
|
280
|
+
vals = max(size, &)
|
281
281
|
dv = reject_values(*DaruLite::MISSING_VALUES)
|
282
282
|
vals.is_a?(Array) ? (vals.map { |x| dv.index_of(x) }) : dv.index_of(vals)
|
283
283
|
end
|
@@ -299,8 +299,8 @@ module DaruLite
|
|
299
299
|
#
|
300
300
|
# dv.index_of_max_by(2) { |i| i.size }
|
301
301
|
# #=> [:j, :d]
|
302
|
-
def index_of_max_by(size = nil, &
|
303
|
-
vals = max_by(size, &
|
302
|
+
def index_of_max_by(size = nil, &)
|
303
|
+
vals = max_by(size, &)
|
304
304
|
dv = reject_values(*DaruLite::MISSING_VALUES)
|
305
305
|
vals.is_a?(Array) ? (vals.map { |x| dv.index_of(x) }) : dv.index_of(vals)
|
306
306
|
end
|
@@ -325,8 +325,8 @@ module DaruLite
|
|
325
325
|
#
|
326
326
|
# dv.index_of_min(2) { |a,b| a.size <=> b.size }
|
327
327
|
# #=> [:t, :d]
|
328
|
-
def index_of_min(size = nil, &
|
329
|
-
vals = min(size, &
|
328
|
+
def index_of_min(size = nil, &)
|
329
|
+
vals = min(size, &)
|
330
330
|
dv = reject_values(*DaruLite::MISSING_VALUES)
|
331
331
|
vals.is_a?(Array) ? (vals.map { |x| dv.index_of(x) }) : dv.index_of(vals)
|
332
332
|
end
|
@@ -348,8 +348,8 @@ module DaruLite
|
|
348
348
|
#
|
349
349
|
# dv.index_of_min(2) { |i| i.size }
|
350
350
|
# #=> [:t, :d]
|
351
|
-
def index_of_min_by(size = nil, &
|
352
|
-
vals = min_by(size, &
|
351
|
+
def index_of_min_by(size = nil, &)
|
352
|
+
vals = min_by(size, &)
|
353
353
|
dv = reject_values(*DaruLite::MISSING_VALUES)
|
354
354
|
vals.is_a?(Array) ? (vals.map { |x| dv.index_of(x) }) : dv.index_of(vals)
|
355
355
|
end
|
@@ -58,8 +58,8 @@ module DaruLite
|
|
58
58
|
# # 0 3 days
|
59
59
|
# # 1 35 days
|
60
60
|
# # 2 14 days
|
61
|
-
def apply_where(bool_array, &
|
62
|
-
DaruLite::Core::Query.vector_apply_where
|
61
|
+
def apply_where(bool_array, &)
|
62
|
+
DaruLite::Core::Query.vector_apply_where(self, bool_array, &)
|
63
63
|
end
|
64
64
|
|
65
65
|
# Keep only unique elements of the vector alongwith their indexes.
|
@@ -17,12 +17,12 @@ module DaruLite
|
|
17
17
|
values.any? { |v| include_with_nan? @data, v }
|
18
18
|
end
|
19
19
|
|
20
|
-
def any?(&
|
21
|
-
@data.data.any?(&
|
20
|
+
def any?(&)
|
21
|
+
@data.data.any?(&)
|
22
22
|
end
|
23
23
|
|
24
|
-
def all?(&
|
25
|
-
@data.data.all?(&
|
24
|
+
def all?(&)
|
25
|
+
@data.data.all?(&)
|
26
26
|
end
|
27
27
|
|
28
28
|
# Returns an array of either none or integer values, indicating the
|
@@ -17,10 +17,10 @@ module DaruLite
|
|
17
17
|
# v = DaruLite::Vector.new ["My first guitar", "jazz", "guitar"]
|
18
18
|
# # Say you want to sort these strings by length.
|
19
19
|
# v.sort(ascending: false) { |a,b| a.length <=> b.length }
|
20
|
-
def sort(opts = {}, &
|
20
|
+
def sort(opts = {}, &)
|
21
21
|
opts = { ascending: true }.merge(opts)
|
22
22
|
|
23
|
-
vector_index = resort_index(@data.each_with_index, opts, &
|
23
|
+
vector_index = resort_index(@data.each_with_index, opts, &)
|
24
24
|
vector, index = vector_index.transpose
|
25
25
|
|
26
26
|
index = @index.reorder index
|
@@ -68,8 +68,8 @@ module DaruLite
|
|
68
68
|
# Just sort the data and get an Array in return using Enumerable#sort.
|
69
69
|
# Non-destructive.
|
70
70
|
# :nocov:
|
71
|
-
def sorted_data(&
|
72
|
-
@data.to_a.sort(&
|
71
|
+
def sorted_data(&)
|
72
|
+
@data.to_a.sort(&)
|
73
73
|
end
|
74
74
|
# :nocov:
|
75
75
|
|
data/lib/daru_lite/vector.rb
CHANGED
@@ -413,7 +413,7 @@ module DaruLite
|
|
413
413
|
|
414
414
|
"#<#{self.class}(#{size})#{':category' if category?}>\n" +
|
415
415
|
Formatters::Table.format(
|
416
|
-
to_a.lazy.
|
416
|
+
to_a.lazy.zip,
|
417
417
|
headers: @name && [@name],
|
418
418
|
row_headers: row_headers,
|
419
419
|
threshold: threshold,
|
@@ -508,7 +508,7 @@ module DaruLite
|
|
508
508
|
DaruLite::DataFrame.new ps
|
509
509
|
end
|
510
510
|
|
511
|
-
DATE_REGEXP = /^(\d{2}-\d{2}-\d{4}|\d{4}-\d{2}-\d{2})
|
511
|
+
DATE_REGEXP = /^(\d{2}-\d{2}-\d{4}|\d{4}-\d{2}-\d{2})$/
|
512
512
|
|
513
513
|
# Returns the database type for the vector, according to its content
|
514
514
|
def db_type
|
@@ -563,10 +563,8 @@ module DaruLite
|
|
563
563
|
dv
|
564
564
|
end
|
565
565
|
|
566
|
-
def method_missing(name, *args, &
|
567
|
-
|
568
|
-
# (string/symbol dychotomy, informative errors) or removed totally. - zverok
|
569
|
-
if name =~ /(.+)=/
|
566
|
+
def method_missing(name, *args, &)
|
567
|
+
if name =~ /^([^=]+)=/
|
570
568
|
self[Regexp.last_match(1).to_sym] = args[0]
|
571
569
|
elsif has_index?(name)
|
572
570
|
self[name]
|
data/lib/daru_lite/version.rb
CHANGED
@@ -128,8 +128,6 @@ shared_examples_for 'a filterable DataFrame' do
|
|
128
128
|
end
|
129
129
|
|
130
130
|
describe "#keep_row_if" do
|
131
|
-
subject { df.keep_row_if { |row| row[:a] % 10 == 0 } }
|
132
|
-
|
133
131
|
let(:index) { [:one, :two, :three, :four, :five] }
|
134
132
|
let(:order) { [:a, :b, :c] }
|
135
133
|
let(:df) do
|
@@ -143,33 +141,194 @@ shared_examples_for 'a filterable DataFrame' do
|
|
143
141
|
)
|
144
142
|
end
|
145
143
|
|
146
|
-
|
144
|
+
shared_examples_for '#keep_row_if' do
|
145
|
+
before { subject }
|
146
|
+
|
147
147
|
it "keeps row if block evaluates to true" do
|
148
|
-
|
149
|
-
|
148
|
+
expect(df).to eq(expected_df)
|
149
|
+
end
|
150
|
+
|
151
|
+
it 'returns correct index' do
|
152
|
+
expect(df.index).to eq(expected_index)
|
153
|
+
end
|
154
|
+
|
155
|
+
it "all vectors have the same index" do
|
156
|
+
expect(df.map(&:index)).to all(eq(expected_index))
|
157
|
+
end
|
158
|
+
end
|
159
|
+
|
160
|
+
context 'a single row is removed' do
|
161
|
+
context DaruLite::Index do
|
162
|
+
subject { df.keep_row_if { |row| row.name != :four } }
|
163
|
+
|
164
|
+
let(:expected_index) { DaruLite::Index.new([:one, :two, :three, :five]) }
|
165
|
+
let(:expected_df) do
|
150
166
|
DaruLite::DataFrame.new(
|
151
|
-
{ b: [10, 12, 20], a: [50, 30, 30], c: [10, 20, 30] },
|
167
|
+
{ b: [10, 12, 20, 30], a: [50, 30, 30, 5], c: [10, 20, 30, 50] },
|
152
168
|
order:,
|
153
|
-
index:
|
169
|
+
index: expected_index
|
154
170
|
)
|
155
|
-
|
171
|
+
end
|
172
|
+
|
173
|
+
it_behaves_like '#keep_row_if'
|
174
|
+
end
|
175
|
+
|
176
|
+
context DaruLite::CategoricalIndex do
|
177
|
+
subject { df.keep_row_if { |row| row.name != :a } }
|
178
|
+
|
179
|
+
let (:index) { DaruLite::CategoricalIndex.new([:a, 1, 1, :a, :c]) }
|
180
|
+
let(:expected_index) { DaruLite::CategoricalIndex.new([1, 1, :c]) }
|
181
|
+
let(:expected_df) do
|
182
|
+
DaruLite::DataFrame.new(
|
183
|
+
{
|
184
|
+
b: [12, 20, 30],
|
185
|
+
a: [30, 30, 5],
|
186
|
+
c: [20, 30, 50]
|
187
|
+
},
|
188
|
+
order:,
|
189
|
+
index: expected_index
|
190
|
+
)
|
191
|
+
end
|
192
|
+
|
193
|
+
it_behaves_like '#keep_row_if'
|
194
|
+
end
|
195
|
+
|
196
|
+
context DaruLite::MultiIndex do
|
197
|
+
subject { df.keep_row_if { |row| !row.name.include?('two') } }
|
198
|
+
|
199
|
+
let(:index) do
|
200
|
+
DaruLite::MultiIndex.from_tuples([[:a, :one], [:a, :two], [:b, :one], [:b, :two], [:c, :one]])
|
201
|
+
end
|
202
|
+
let(:expected_index) do
|
203
|
+
DaruLite::MultiIndex.from_tuples([[:a, :one], [:b, :one], [:c, :one]])
|
204
|
+
end
|
205
|
+
let(:expected_df) do
|
206
|
+
DaruLite::DataFrame.new(
|
207
|
+
{
|
208
|
+
b: [10, 20, 30],
|
209
|
+
a: [50, 30, 5],
|
210
|
+
c: [10, 30, 50]
|
211
|
+
},
|
212
|
+
order:,
|
213
|
+
index: expected_index
|
214
|
+
)
|
215
|
+
end
|
216
|
+
|
217
|
+
it_behaves_like '#keep_row_if'
|
156
218
|
end
|
157
219
|
end
|
158
220
|
|
159
|
-
context
|
160
|
-
|
221
|
+
context 'several rows are removed' do
|
222
|
+
subject { df.keep_row_if { |row| row[:a] % 10 == 0 } }
|
161
223
|
|
162
|
-
|
163
|
-
|
164
|
-
|
224
|
+
context DaruLite::Index do
|
225
|
+
let(:expected_index) { DaruLite::Index.new([:one, :two, :three]) }
|
226
|
+
let(:expected_df) do
|
227
|
+
DaruLite::DataFrame.new(
|
228
|
+
{ b: [10, 12, 20], a: [50, 30, 30], c: [10, 20, 30] },
|
229
|
+
order:,
|
230
|
+
index: expected_index
|
231
|
+
)
|
232
|
+
end
|
233
|
+
|
234
|
+
it_behaves_like '#keep_row_if'
|
235
|
+
end
|
236
|
+
|
237
|
+
context DaruLite::CategoricalIndex do
|
238
|
+
let (:index) { DaruLite::CategoricalIndex.new([:a, 1, 1, :a, :c]) }
|
239
|
+
let(:expected_index) { DaruLite::CategoricalIndex.new([:a, 1, 1]) }
|
240
|
+
let(:expected_df) do
|
165
241
|
DaruLite::DataFrame.new(
|
166
242
|
{ b: [10, 12, 20], a: [50, 30, 30], c: [10, 20, 30] },
|
167
243
|
order:,
|
168
|
-
index:
|
244
|
+
index: expected_index
|
169
245
|
)
|
170
|
-
|
246
|
+
end
|
247
|
+
|
248
|
+
it_behaves_like '#keep_row_if'
|
249
|
+
end
|
250
|
+
|
251
|
+
context DaruLite::MultiIndex do
|
252
|
+
let(:index) { DaruLite::MultiIndex.from_tuples([[:a, :one], [:a, :two], [:b, :one], [:b, :two], [:c, :one]]) }
|
253
|
+
let(:expected_index) do
|
254
|
+
DaruLite::MultiIndex.from_tuples([[:a, :one], [:a, :two], [:b, :one]])
|
255
|
+
end
|
256
|
+
let(:expected_df) do
|
257
|
+
DaruLite::DataFrame.new(
|
258
|
+
{ b: [10, 12, 20], a: [50, 30, 30], c: [10, 20, 30] },
|
259
|
+
order:,
|
260
|
+
index: expected_index
|
261
|
+
)
|
262
|
+
end
|
263
|
+
|
264
|
+
it_behaves_like '#keep_row_if'
|
171
265
|
end
|
172
266
|
end
|
267
|
+
|
268
|
+
# context DaruLite::MultiIndex do
|
269
|
+
# subject { df.keep_row_if { |row| row.name != 'No answer' } }
|
270
|
+
|
271
|
+
# let(:df) do
|
272
|
+
# order = DaruLite::MultiIndex.from_tuples(
|
273
|
+
# [
|
274
|
+
# [:a, :total],
|
275
|
+
# [:a, "Male"],
|
276
|
+
# [:a, "Female"],
|
277
|
+
# [:a, "Prefer not to answer"],
|
278
|
+
# [:a, "No answer"],
|
279
|
+
# [:b, :total],
|
280
|
+
# [:b, "Male"],
|
281
|
+
# [:b, "Female"],
|
282
|
+
# [:b, "Prefer not to answer"],
|
283
|
+
# [:b, "No answer"],
|
284
|
+
# [:c, :total],
|
285
|
+
# [:c, "Male"],
|
286
|
+
# [:c, "Female"],
|
287
|
+
# [:c, "Prefer not to answer"],
|
288
|
+
# [:c, "No answer"]
|
289
|
+
# ]
|
290
|
+
# )
|
291
|
+
# index = [
|
292
|
+
# :base,
|
293
|
+
# "Single Malt Whisky",
|
294
|
+
# "Blended/ Other Whisky",
|
295
|
+
# "Vodka",
|
296
|
+
# "Cognac",
|
297
|
+
# "Brandy",
|
298
|
+
# "Rum",
|
299
|
+
# "Gin",
|
300
|
+
# "Tequila",
|
301
|
+
# "No answer",
|
302
|
+
# "NET"
|
303
|
+
# ]
|
304
|
+
# DaruLite::DataFrame.new(
|
305
|
+
# [
|
306
|
+
# [0.0, nil, nil, nil, nil, nil, nil, nil, nil],
|
307
|
+
# [nil, nil, nil, nil, nil, nil, nil, nil, nil],
|
308
|
+
# [nil, nil, nil, nil, nil, nil, nil, nil, nil],
|
309
|
+
# [nil, nil, nil, nil, nil, nil, nil, nil, nil],
|
310
|
+
# [nil, nil, nil, nil, nil, nil, nil, nil, nil],
|
311
|
+
# [Float::NAN, nil, nil, nil, nil, nil, nil, nil, nil],
|
312
|
+
# [nil, nil, nil, nil, nil, nil, nil, nil, nil],
|
313
|
+
# [nil, nil, nil, nil, nil, nil, nil, nil, nil],
|
314
|
+
# [nil, nil, nil, nil, nil, nil, nil, nil, nil],
|
315
|
+
# [nil, nil, nil, nil, nil, nil, nil, nil, nil],
|
316
|
+
# [0, nil, nil, nil, nil, nil, nil, nil, nil],
|
317
|
+
# [0, nil, nil, nil, nil, nil, nil, nil, nil],
|
318
|
+
# [0, nil, nil, nil, nil, nil, nil, nil, nil],
|
319
|
+
# [0, nil, nil, nil, nil, nil, nil, nil, nil],
|
320
|
+
# [0, nil, nil, nil, nil, nil, nil, nil, nil],
|
321
|
+
# ],
|
322
|
+
# index:,
|
323
|
+
# order:
|
324
|
+
# )
|
325
|
+
# end
|
326
|
+
|
327
|
+
# it "all vectors have the same index" do
|
328
|
+
# subject
|
329
|
+
# expect(df.map(&:index)).to all(eq(df.index))
|
330
|
+
# end
|
331
|
+
# end
|
173
332
|
end
|
174
333
|
|
175
334
|
describe "#keep_vector_if" do
|
@@ -1,36 +1,47 @@
|
|
1
1
|
require 'spec_helper.rb'
|
2
2
|
|
3
3
|
describe DaruLite::CategoricalIndex do
|
4
|
+
let(:index) { described_class.new(keys) }
|
5
|
+
let(:keys) { [:a, :b, :a, :a, :c] }
|
6
|
+
|
7
|
+
describe "#to_a" do
|
8
|
+
subject { index.to_a }
|
9
|
+
|
10
|
+
it { is_expected.to eq(keys) }
|
11
|
+
|
12
|
+
it 'the returns array is not a variable of the index' do
|
13
|
+
expect { subject << 'four' }.not_to change { index.to_a }
|
14
|
+
end
|
15
|
+
end
|
16
|
+
|
4
17
|
context "#pos" do
|
5
18
|
context "when the category is non-numeric" do
|
6
|
-
let(:idx) { described_class.new [:a, :b, :a, :a, :c] }
|
7
|
-
|
8
19
|
context "single category" do
|
9
|
-
subject {
|
20
|
+
subject { index.pos :a }
|
10
21
|
|
11
22
|
it { is_expected.to eq [0, 2, 3] }
|
12
23
|
end
|
13
24
|
|
14
25
|
context "multiple categories" do
|
15
|
-
subject {
|
26
|
+
subject { index.pos :a, :c }
|
16
27
|
|
17
28
|
it { is_expected.to eq [0, 2, 3, 4] }
|
18
29
|
end
|
19
30
|
|
20
31
|
context "invalid category" do
|
21
|
-
it { expect {
|
32
|
+
it { expect { index.pos :e }.to raise_error IndexError }
|
22
33
|
end
|
23
34
|
|
24
35
|
context "positional index" do
|
25
|
-
it { expect(
|
36
|
+
it { expect(index.pos 0).to eq 0 }
|
26
37
|
end
|
27
38
|
|
28
39
|
context "invalid positional index" do
|
29
|
-
it { expect {
|
40
|
+
it { expect { index.pos 5 }.to raise_error IndexError }
|
30
41
|
end
|
31
42
|
|
32
43
|
context "multiple positional indexes" do
|
33
|
-
subject {
|
44
|
+
subject { index.pos 0, 1, 2 }
|
34
45
|
|
35
46
|
it { is_expected.to be_a Array }
|
36
47
|
its(:size) { is_expected.to eq 3 }
|
@@ -167,4 +178,12 @@ describe DaruLite::CategoricalIndex do
|
|
167
178
|
it { expect(idx.valid? :a, 1, 5).to eq false }
|
168
179
|
end
|
169
180
|
end
|
181
|
+
|
182
|
+
describe '#delete_at' do
|
183
|
+
subject { index.delete_at(3) }
|
184
|
+
|
185
|
+
let(:index) { described_class.new([:a, 1, :a, 1, 'c']) }
|
186
|
+
|
187
|
+
it { is_expected.to eq(described_class.new([:a, 1, :a, 'c'])) }
|
188
|
+
end
|
170
189
|
end
|
data/spec/index/index_spec.rb
CHANGED
@@ -1,6 +1,9 @@
|
|
1
1
|
require 'spec_helper.rb'
|
2
2
|
|
3
3
|
describe DaruLite::Index do
|
4
|
+
let(:index) { described_class.new(keys) }
|
5
|
+
let(:keys) { ['one', 'two', 'three'] }
|
6
|
+
|
4
7
|
context ".new" do
|
5
8
|
it "creates an Index object if Index-like data is supplied" do
|
6
9
|
i = DaruLite::Index.new [:one, 'one', 1, 2, :two]
|
@@ -147,6 +150,16 @@ describe DaruLite::Index do
|
|
147
150
|
end
|
148
151
|
end
|
149
152
|
|
153
|
+
describe "#to_a" do
|
154
|
+
subject { index.to_a }
|
155
|
+
|
156
|
+
it { is_expected.to eq(keys) }
|
157
|
+
|
158
|
+
it 'the returns array is not a variable of the index' do
|
159
|
+
expect { subject << 'four' }.not_to change { index.to_a }
|
160
|
+
end
|
161
|
+
end
|
162
|
+
|
150
163
|
context "#&" do
|
151
164
|
before :each do
|
152
165
|
@left = DaruLite::Index.new [:miles, :geddy, :eric]
|
@@ -390,11 +403,11 @@ describe DaruLite::Index do
|
|
390
403
|
end
|
391
404
|
|
392
405
|
describe '#delete_at' do
|
393
|
-
subject {
|
406
|
+
subject { index.delete_at(1) }
|
394
407
|
|
395
|
-
let(:
|
408
|
+
let(:index) { described_class.new([:a, :b, 1, 2]) }
|
396
409
|
|
397
|
-
it { is_expected.to eq
|
410
|
+
it { is_expected.to eq(described_class.new([:a, 1, 2])) }
|
398
411
|
end
|
399
412
|
|
400
413
|
context '#to_df' do
|