Class: Daru::MultiIndex
- Inherits:
-
Index
show all
- Defined in:
- lib/daru/index/multi_index.rb
Overview
rubocop:disable Metrics/ClassLength
Instance Attribute Summary collapse
Attributes inherited from Index
#name, #relation_hash
Class Method Summary
collapse
Instance Method Summary
collapse
Methods inherited from Index
__new__, #_dump, _load, coerce, inherited, #is_values, new, #slice, #sort, #subset_slice
Constructor Details
#initialize(opts = {}) ⇒ MultiIndex
names and levels should be of same size. If size of Array ‘name` is less or greater than size of array `levels` then it raises `SizeError`. If user don’t want to put name for particular level then user must put empty string in that index of Array ‘name`. For example there is multi_index of 3 levels and user don’t want to name level 0, then do mulit_index.name = [”, ‘level1_name1’, ‘level2_name’]
79
80
81
82
83
84
85
86
87
88
89
90
|
# File 'lib/daru/index/multi_index.rb', line 79
def initialize opts={}
labels = opts[:labels]
levels = opts[:levels]
raise ArgumentError, 'Must specify both labels and levels' unless labels && levels
raise ArgumentError, 'Labels and levels should be same size' if labels.size != levels.size
raise ArgumentError, 'Incorrect labels and levels' if incorrect_fields?(labels, levels)
@labels = labels
@levels = levels.map { |e| e.map.with_index.to_h }
self.name = opts[:name] unless opts[:name].nil?
end
|
Instance Attribute Details
Returns the value of attribute labels.
11
12
13
|
# File 'lib/daru/index/multi_index.rb', line 11
def labels
@labels
end
|
Class Method Details
.from_arrays(arrays) ⇒ Object
105
106
107
108
109
110
111
112
113
114
|
# File 'lib/daru/index/multi_index.rb', line 105
def self.from_arrays arrays
levels = arrays.map { |e| e.uniq.sort_by(&:to_s) }
labels = arrays.each_with_index.map do |arry, level_index|
level = levels[level_index]
arry.map { |lvl| level.index(lvl) }
end
MultiIndex.new labels: labels, levels: levels
end
|
.from_tuples(tuples) ⇒ Object
116
117
118
|
# File 'lib/daru/index/multi_index.rb', line 116
def self.from_tuples tuples
from_arrays tuples.transpose
end
|
.try_from_tuples(tuples) ⇒ Object
120
121
122
123
124
125
126
|
# File 'lib/daru/index/multi_index.rb', line 120
def self.try_from_tuples tuples
if tuples.respond_to?(:first) && tuples.first.is_a?(Array)
from_tuples(tuples)
else
nil
end
end
|
Instance Method Details
299
300
301
|
# File 'lib/daru/index/multi_index.rb', line 299
def & other
MultiIndex.from_tuples(to_a & other.to_a)
end
|
#==(other) ⇒ Object
322
323
324
325
326
|
# File 'lib/daru/index/multi_index.rb', line 322
def == other
self.class == other.class &&
labels == other.labels &&
levels == other.levels
end
|
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
|
# File 'lib/daru/index/multi_index.rb', line 128
def [] *key
key.flatten!
case
when key[0].is_a?(Range)
retrieve_from_range(key[0])
when key[0].is_a?(Integer) && key.size == 1
try_retrieve_from_integer(key[0])
else
begin
retrieve_from_tuples key
rescue NoMethodError
raise IndexError, "Specified index #{key.inspect} do not exist"
end
end
end
|
#at(*positions) ⇒ object
Takes positional values and returns subset of the self
capturing the indexes at mentioned positions
188
189
190
191
192
193
194
195
196
|
# File 'lib/daru/index/multi_index.rb', line 188
def at *positions
positions = preprocess_positions(*positions)
validate_positions(*positions)
if positions.is_a? Integer
key(positions)
else
Daru::MultiIndex.from_tuples positions.map(&method(:key))
end
end
|
#coerce_index ⇒ Object
250
251
252
253
254
255
256
257
258
259
260
261
262
|
# File 'lib/daru/index/multi_index.rb', line 250
def coerce_index
if @levels.size == 1
elements = to_a.flatten
if elements.uniq.length == elements.length
Daru::Index.new(elements)
else
Daru::CategoricalIndex.new(elements)
end
else
self
end
end
|
Provide a MultiIndex for sub vector produced
350
351
352
353
|
# File 'lib/daru/index/multi_index.rb', line 350
def conform input_indexes
return self if input_indexes[0].is_a? Range
drop_left_level input_indexes.size
end
|
#drop_left_level(by = 1) ⇒ Object
291
292
293
|
# File 'lib/daru/index/multi_index.rb', line 291
def drop_left_level by=1
MultiIndex.from_arrays to_a.transpose[by..-1]
end
|
287
288
289
|
# File 'lib/daru/index/multi_index.rb', line 287
def dup
MultiIndex.new levels: levels.dup, labels: labels.dup, name: (@name.nil? ? nil : @name.dup)
end
|
#each(&block) ⇒ Object
3
4
5
|
# File 'lib/daru/index/multi_index.rb', line 3
def each(&block)
to_a.each(&block)
end
|
#empty? ⇒ Boolean
303
304
305
|
# File 'lib/daru/index/multi_index.rb', line 303
def empty?
@labels.flatten.empty? && @levels.all?(&:empty?)
end
|
#include?(tuple) ⇒ Boolean
307
308
309
310
311
312
|
# File 'lib/daru/index/multi_index.rb', line 307
def include? tuple
return false unless tuple.is_a? Enumerable
@labels[0...tuple.flatten.size]
.transpose
.include?(tuple.flatten.each_with_index.map { |e, i| @levels[i][e] })
end
|
#inspect(threshold = 20) ⇒ Object
336
337
338
339
|
# File 'lib/daru/index/multi_index.rb', line 336
def inspect threshold=20
"#<Daru::MultiIndex(#{size}x#{width})>\n" +
Formatters::Table.format([], headers: @name, row_headers: sparse_tuples, threshold: threshold)
end
|
#key(index) ⇒ Object
279
280
281
282
283
284
285
|
# File 'lib/daru/index/multi_index.rb', line 279
def key index
raise ArgumentError, "Key #{index} is too large" if index >= @labels[0].size
@labels
.each_with_index
.map { |label, i| @levels[i].keys[label[index]] }
end
|
13
14
15
|
# File 'lib/daru/index/multi_index.rb', line 13
def levels
@levels.map(&:keys)
end
|
#map(&block) ⇒ Object
7
8
9
|
# File 'lib/daru/index/multi_index.rb', line 7
def map(&block)
to_a.map(&block)
end
|
#name=(names) ⇒ Object
92
93
94
95
|
# File 'lib/daru/index/multi_index.rb', line 92
def name=(names)
validate_name names, @labels
@name = names
end
|
#pos(*indexes) ⇒ Object
Note:
If the arugent is both a valid index and a valid position, it will treated as valid index
Returns positions given indexes or positions
160
161
162
163
164
165
166
167
168
|
# File 'lib/daru/index/multi_index.rb', line 160
def pos *indexes
if indexes.first.is_a? Integer
return indexes.first if indexes.size == 1
return indexes
end
res = self[indexes]
return res if res.is_a? Integer
res.map { |i| self[i] }
end
|
#remove_layer(layer_index) ⇒ Object
242
243
244
245
246
247
248
|
# File 'lib/daru/index/multi_index.rb', line 242
def remove_layer layer_index
@levels.delete_at(layer_index)
@labels.delete_at(layer_index)
@name.delete_at(layer_index) unless @name.nil?
coerce_index
end
|
#reorder(new_order) ⇒ Object
202
203
204
205
|
# File 'lib/daru/index/multi_index.rb', line 202
def reorder(new_order)
from = to_a
self.class.from_tuples(new_order.map { |i| from[i] })
end
|
314
315
316
|
# File 'lib/daru/index/multi_index.rb', line 314
def size
@labels[0].size
end
|
#sparse_tuples ⇒ Object
Return tuples with nils in place of repeating values, like this:
- :a , :bar, :one
- nil, nil , :two
- nil, :foo, :one
361
362
363
364
365
366
367
|
# File 'lib/daru/index/multi_index.rb', line 361
def sparse_tuples
tuples = to_a
[tuples.first] + each_cons(2).map { |prev, cur|
left = cur.zip(prev).drop_while { |c, p| c == p }
[nil] * (cur.size - left.size) + left.map(&:first)
}
end
|
#subset(*indexes) ⇒ Object
170
171
172
173
174
175
176
|
# File 'lib/daru/index/multi_index.rb', line 170
def subset *indexes
if indexes.first.is_a? Integer
MultiIndex.from_tuples(indexes.map { |index| key(index) })
else
self[indexes].conform indexes
end
end
|
328
329
330
|
# File 'lib/daru/index/multi_index.rb', line 328
def to_a
(0...size).map { |e| key(e) }
end
|
341
342
343
344
|
# File 'lib/daru/index/multi_index.rb', line 341
def to_html
path = File.expand_path('../../iruby/templates/multi_index.html.erb', __FILE__)
ERB.new(File.read(path).strip).result(binding)
end
|
#try_retrieve_from_integer(int) ⇒ Object
207
208
209
|
# File 'lib/daru/index/multi_index.rb', line 207
def try_retrieve_from_integer int
@levels[0].key?(int) ? retrieve_from_tuples([int]) : int
end
|
#valid?(*indexes) ⇒ Boolean
144
145
146
147
148
149
150
|
# File 'lib/daru/index/multi_index.rb', line 144
def valid? *indexes
pos(*indexes)
return true
rescue IndexError
return false
end
|
332
333
334
|
# File 'lib/daru/index/multi_index.rb', line 332
def values
Array.new(size) { |i| i }
end
|
318
319
320
|
# File 'lib/daru/index/multi_index.rb', line 318
def width
@levels.size
end
|
295
296
297
|
# File 'lib/daru/index/multi_index.rb', line 295
def | other
MultiIndex.from_tuples(to_a | other.to_a)
end
|