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
#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 multi_index.name = [”, ‘level1_name1’, ‘level2_name’]
80
81
82
83
84
85
86
87
88
89
90
91
|
# File 'lib/daru/index/multi_index.rb', line 80
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
|
Returns the value of attribute name.
12
13
14
|
# File 'lib/daru/index/multi_index.rb', line 12
def name
@name
end
|
Class Method Details
.from_arrays(arrays) ⇒ Object
106
107
108
109
110
111
112
113
114
115
|
# File 'lib/daru/index/multi_index.rb', line 106
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
117
118
119
|
# File 'lib/daru/index/multi_index.rb', line 117
def self.from_tuples tuples
from_arrays tuples.transpose
end
|
.try_from_tuples(tuples) ⇒ Object
121
122
123
124
125
126
127
|
# File 'lib/daru/index/multi_index.rb', line 121
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
300
301
302
|
# File 'lib/daru/index/multi_index.rb', line 300
def & other
MultiIndex.from_tuples(to_a & other.to_a)
end
|
#==(other) ⇒ Object
323
324
325
326
327
|
# File 'lib/daru/index/multi_index.rb', line 323
def == other
self.class == other.class &&
labels == other.labels &&
levels == other.levels
end
|
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
|
# File 'lib/daru/index/multi_index.rb', line 129
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
|
#add(*indexes) ⇒ Object
199
200
201
|
# File 'lib/daru/index/multi_index.rb', line 199
def add *indexes
Daru::MultiIndex.from_tuples(to_a + [indexes])
end
|
#at(*positions) ⇒ object
Takes positional values and returns subset of the self
capturing the indexes at mentioned positions
189
190
191
192
193
194
195
196
197
|
# File 'lib/daru/index/multi_index.rb', line 189
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
251
252
253
254
255
256
257
258
259
260
261
262
263
|
# File 'lib/daru/index/multi_index.rb', line 251
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
351
352
353
354
|
# File 'lib/daru/index/multi_index.rb', line 351
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
292
293
294
|
# File 'lib/daru/index/multi_index.rb', line 292
def drop_left_level by=1
MultiIndex.from_arrays to_a.transpose[by..-1]
end
|
288
289
290
|
# File 'lib/daru/index/multi_index.rb', line 288
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
304
305
306
|
# File 'lib/daru/index/multi_index.rb', line 304
def empty?
@labels.flatten.empty? && @levels.all?(&:empty?)
end
|
#include?(tuple) ⇒ Boolean
308
309
310
311
312
313
|
# File 'lib/daru/index/multi_index.rb', line 308
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
337
338
339
340
|
# File 'lib/daru/index/multi_index.rb', line 337
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
280
281
282
283
284
285
286
|
# File 'lib/daru/index/multi_index.rb', line 280
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
|
14
15
16
|
# File 'lib/daru/index/multi_index.rb', line 14
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
|
#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
161
162
163
164
165
166
167
168
169
|
# File 'lib/daru/index/multi_index.rb', line 161
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
243
244
245
246
247
248
249
|
# File 'lib/daru/index/multi_index.rb', line 243
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
203
204
205
206
|
# File 'lib/daru/index/multi_index.rb', line 203
def reorder(new_order)
from = to_a
MultiIndex.from_tuples(new_order.map { |i| from[i] })
end
|
315
316
317
|
# File 'lib/daru/index/multi_index.rb', line 315
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
362
363
364
365
366
367
368
|
# File 'lib/daru/index/multi_index.rb', line 362
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
171
172
173
174
175
176
177
|
# File 'lib/daru/index/multi_index.rb', line 171
def subset *indexes
if indexes.first.is_a? Integer
MultiIndex.from_tuples(indexes.map { |index| key(index) })
else
self[indexes].conform indexes
end
end
|
329
330
331
|
# File 'lib/daru/index/multi_index.rb', line 329
def to_a
(0...size).map { |e| key(e) }
end
|
370
371
372
|
# File 'lib/daru/index/multi_index.rb', line 370
def to_df
Daru::DataFrame.new(@name.zip(to_a.transpose).to_h)
end
|
342
343
344
345
|
# File 'lib/daru/index/multi_index.rb', line 342
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
208
209
210
|
# File 'lib/daru/index/multi_index.rb', line 208
def try_retrieve_from_integer int
@levels[0].key?(int) ? retrieve_from_tuples([int]) : int
end
|
#valid?(*indexes) ⇒ Boolean
145
146
147
148
149
150
151
|
# File 'lib/daru/index/multi_index.rb', line 145
def valid? *indexes
pos(*indexes)
return true
rescue IndexError
return false
end
|
333
334
335
|
# File 'lib/daru/index/multi_index.rb', line 333
def values
Array.new(size) { |i| i }
end
|
319
320
321
|
# File 'lib/daru/index/multi_index.rb', line 319
def width
@levels.size
end
|
296
297
298
|
# File 'lib/daru/index/multi_index.rb', line 296
def | other
MultiIndex.from_tuples(to_a | other.to_a)
end
|