Class: DaruLite::DateTimeIndex
- Includes:
- Enumerable
- Defined in:
- lib/daru_lite/date_time/index.rb
Constant Summary collapse
- Helper =
DateTimeIndexHelper
Instance Attribute Summary collapse
-
#frequency ⇒ Object
readonly
Returns the value of attribute frequency.
-
#keys ⇒ Object
readonly
Returns the value of attribute keys.
-
#offset ⇒ Object
readonly
Returns the value of attribute offset.
-
#periods ⇒ Object
readonly
Returns the value of attribute periods.
Attributes inherited from Index
Class Method Summary collapse
- ._load(data) ⇒ Object
-
.date_range(opts = {}) ⇒ DateTimeIndex
Create a date range by specifying the start, end, periods and frequency of the data.
- .try_create(source) ⇒ Object
Instance Method Summary collapse
- #==(other) ⇒ Object
-
#[](*key) ⇒ Object
Retreive a slice or a an individual index number from the index.
-
#_dump(_depth) ⇒ Object
:nocov:.
-
#day ⇒ Array<Integer>
Array containing day of each index.
-
#dup ⇒ Object
Custom dup method for DateTimeIndex.
- #each(&block) ⇒ Object
-
#empty? ⇒ Boolean
Return true if the DateTimeIndex is empty.
-
#hour ⇒ Array<Integer>
Array containing hour of each index.
-
#include?(date_time) ⇒ Boolean
Check if a date exists in the index.
-
#initialize(data, opts = { freq: nil }) ⇒ DateTimeIndex
constructor
Create a DateTimeIndex with or without a frequency in data.
- #inspect ⇒ Object
-
#lag(distance) ⇒ DateTimeIndex
Shift all dates in the index to the past.
-
#min ⇒ Array<Integer>
Array containing minutes of each index.
-
#month ⇒ Array<Integer>
Array containing month of each index.
- #pos(*args) ⇒ Object
-
#sec ⇒ Array<Integer>
Array containing seconds of each index.
-
#shift(distance) ⇒ DateTimeIndex
Shift all dates in the index by a positive number in the future.
-
#size ⇒ Object
Size of index.
-
#slice(first, last) ⇒ Object
Retrive a slice of the index by specifying first and last members of the slice.
- #subset(*args) ⇒ Object
-
#to_a ⇒ Array<DateTime>
Return the DateTimeIndex as an Array of DateTime objects.
- #valid?(*args) ⇒ Boolean
-
#year ⇒ Array<Integer>
Array containing year of each index.
Methods inherited from Index
#&, __new__, #add, #at, coerce, #conform, inherited, #is_values, #key, new, #reorder, #sort, #subset_slice, #to_df, #|
Constructor Details
#initialize(data, opts = { freq: nil }) ⇒ DateTimeIndex
Create a DateTimeIndex with or without a frequency in data. The constructor should be used for creating DateTimeIndex by directly passing in DateTime objects or date-like strings, typically in cases where values with frequency are not needed.
255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 |
# File 'lib/daru_lite/date_time/index.rb', line 255 def initialize(data, opts = { freq: nil }) super(data) Helper.possibly_convert_to_date_time data @offset = case opts[:freq] when :infer then Helper.infer_offset(data) when nil then nil else Helper.offset_from_frequency(opts[:freq]) end @frequency = @offset&.freq_string @data = data.each_with_index.to_a.sort_by(&:first) @periods = data.size end |
Instance Attribute Details
#frequency ⇒ Object (readonly)
Returns the value of attribute frequency.
229 230 231 |
# File 'lib/daru_lite/date_time/index.rb', line 229 def frequency @frequency end |
#keys ⇒ Object (readonly)
Returns the value of attribute keys.
229 230 231 |
# File 'lib/daru_lite/date_time/index.rb', line 229 def keys @keys end |
#offset ⇒ Object (readonly)
Returns the value of attribute offset.
229 230 231 |
# File 'lib/daru_lite/date_time/index.rb', line 229 def offset @offset end |
#periods ⇒ Object (readonly)
Returns the value of attribute periods.
229 230 231 |
# File 'lib/daru_lite/date_time/index.rb', line 229 def periods @periods end |
Class Method Details
._load(data) ⇒ Object
479 480 481 482 483 |
# File 'lib/daru_lite/date_time/index.rb', line 479 def self._load(data) h = Marshal.load data DaruLite::DateTimeIndex.new(h[:data], freq: h[:freq]) end |
.date_range(opts = {}) ⇒ DateTimeIndex
Create a date range by specifying the start, end, periods and frequency of the data.
Notes
If you specify :start and :end options as strings, they can be complete or partial dates and daru will intelligently infer the date from the string directly. However, note that the date-like string must be in the format ‘YYYY-MM-DD HH:MM:SS`.
The string aliases supported by the :freq option are as follows:
-
‘S’ - seconds
-
‘M’ - minutes
-
‘H’ - hours
-
‘D’ - days
-
‘W’ - Week (default) anchored on sunday
-
‘W-SUN’ - Same as ‘W’
-
‘W-MON’ - Week anchored on monday
-
‘W-TUE’ - Week anchored on tuesday
-
‘W-WED’ - Week anchored on wednesday
-
‘W-THU’ - Week anchored on thursday
-
‘W-FRI’ - Week anchored on friday
-
‘W-SAT’ - Week anchored on saturday
-
‘MONTH’ - Month
-
‘YEAR’ - One year
-
‘MB’ - month begin
-
‘ME’ - month end
-
‘YB’ - year begin
-
‘YE’ - year end
Multiples of these can also be specified. For example ‘2S’ for 2 seconds or ‘2ME’ for two month end offsets.
Currently the precision of DateTimeIndex is upto seconds only, though this will improve in the future.
335 336 337 338 339 340 341 342 343 |
# File 'lib/daru_lite/date_time/index.rb', line 335 def self.date_range(opts = {}) start = Helper.coerce_date opts[:start] en = Helper.coerce_date opts[:end] Helper.verify_start_and_end(start, en) unless en.nil? offset = Helper.offset_from_frequency opts[:freq] data = Helper.generate_data start, en, offset, opts[:periods] DateTimeIndex.new(data, freq: offset) end |
.try_create(source) ⇒ Object
221 222 223 |
# File 'lib/daru_lite/date_time/index.rb', line 221 def self.try_create(source) new(source, freq: :infer) if source && ArrayHelper.array_of?(source, ::DateTime) end |
Instance Method Details
#==(other) ⇒ Object
419 420 421 |
# File 'lib/daru_lite/date_time/index.rb', line 419 def ==(other) to_a == other.to_a end |
#[](*key) ⇒ Object
Retreive a slice or a an individual index number from the index.
349 350 351 352 353 354 355 356 357 358 359 360 361 362 363 364 365 366 367 368 |
# File 'lib/daru_lite/date_time/index.rb', line 349 def [](*key) return slice(*key) if key.size != 1 key = key[0] case key when Numeric key when DateTime Helper.find_index_of_date(@data, key) when Range # FIXME: get_by_range is suspiciously close to just #slice, # but one of specs fails when replacing it with just slice get_by_range(key.first, key.last) else raise ArgumentError, "Key #{key} is out of bounds" if Helper.key_out_of_bounds?(key, @data) slice(*Helper.find_date_string_bounds(key)) end end |
#_dump(_depth) ⇒ Object
:nocov:
475 476 477 |
# File 'lib/daru_lite/date_time/index.rb', line 475 def _dump(_depth) Marshal.dump(data: to_a, freq: @offset) end |
#day ⇒ Array<Integer>
Returns Array containing day of each index.
498 499 500 501 502 503 504 |
# File 'lib/daru_lite/date_time/index.rb', line 498 %i[year month day hour min sec].each do |meth| define_method(meth) do each_with_object([]) do |d, arr| arr << d.send(meth) end end end |
#dup ⇒ Object
Custom dup method for DateTimeIndex
273 274 275 |
# File 'lib/daru_lite/date_time/index.rb', line 273 def dup DaruLite::DateTimeIndex.new(@data.transpose[0], freq: @offset) end |
#each(&block) ⇒ Object
225 226 227 |
# File 'lib/daru_lite/date_time/index.rb', line 225 def each(&block) to_a.each(&block) end |
#empty? ⇒ Boolean
Return true if the DateTimeIndex is empty.
521 522 523 |
# File 'lib/daru_lite/date_time/index.rb', line 521 def empty? @data.empty? end |
#hour ⇒ Array<Integer>
Returns Array containing hour of each index.
498 499 500 501 502 503 504 |
# File 'lib/daru_lite/date_time/index.rb', line 498 %i[year month day hour min sec].each do |meth| define_method(meth) do each_with_object([]) do |d, arr| arr << d.send(meth) end end end |
#include?(date_time) ⇒ Boolean
Check if a date exists in the index. Will be inferred from string in case you pass a string. Recommened specifying the full date as a DateTime object.
508 509 510 511 512 513 514 515 516 517 518 |
# File 'lib/daru_lite/date_time/index.rb', line 508 def include?(date_time) return false unless date_time.is_a?(String) || date_time.is_a?(DateTime) if date_time.is_a?(String) date_precision = Helper.determine_date_precision_of date_time date_time = Helper.date_time_from date_time, date_precision end result, = @data.bsearch { |d| d[0] >= date_time } result && result == date_time end |
#inspect ⇒ Object
423 424 425 426 427 428 429 |
# File 'lib/daru_lite/date_time/index.rb', line 423 def inspect = [@periods, @frequency ? "frequency=#{@frequency}" : nil].compact.join(', ') return "#<#{self.class}(#{})>" if @data.empty? "#<#{self.class}(#{}) " \ "#{@data.first[0]}...#{@data.last[0]}>" end |
#lag(distance) ⇒ DateTimeIndex
Shift all dates in the index to the past. The dates are shifted by the same amount as that specified in the offset.
467 468 469 470 471 472 |
# File 'lib/daru_lite/date_time/index.rb', line 467 def lag(distance) distance.is_a?(Integer) && distance.negative? and raise IndexError, "Distance #{distance} cannot be negative" _shift(-distance) end |
#min ⇒ Array<Integer>
Returns Array containing minutes of each index.
498 499 500 501 502 503 504 |
# File 'lib/daru_lite/date_time/index.rb', line 498 %i[year month day hour min sec].each do |meth| define_method(meth) do each_with_object([]) do |d, arr| arr << d.send(meth) end end end |
#month ⇒ Array<Integer>
Returns Array containing month of each index.
498 499 500 501 502 503 504 |
# File 'lib/daru_lite/date_time/index.rb', line 498 %i[year month day hour min sec].each do |meth| define_method(meth) do each_with_object([]) do |d, arr| arr << d.send(meth) end end end |
#pos(*args) ⇒ Object
370 371 372 373 374 375 376 |
# File 'lib/daru_lite/date_time/index.rb', line 370 def pos(*args) # to filled out = self[*args] return out if out.is_a? Numeric out.map { |date| self[date] } end |
#sec ⇒ Array<Integer>
Returns Array containing seconds of each index.
498 499 500 501 502 503 504 |
# File 'lib/daru_lite/date_time/index.rb', line 498 %i[year month day hour min sec].each do |meth| define_method(meth) do each_with_object([]) do |d, arr| arr << d.send(meth) end end end |
#shift(distance) ⇒ DateTimeIndex
Shift all dates in the index by a positive number in the future. The dates are shifted by the same amount as that specified in the offset.
451 452 453 454 455 456 |
# File 'lib/daru_lite/date_time/index.rb', line 451 def shift(distance) distance.is_a?(Integer) && distance.negative? and raise IndexError, "Distance #{distance} cannot be negative" _shift(distance) end |
#size ⇒ Object
Size of index.
415 416 417 |
# File 'lib/daru_lite/date_time/index.rb', line 415 def size @periods end |
#slice(first, last) ⇒ Object
Retrive a slice of the index by specifying first and last members of the slice.
393 394 395 396 397 398 399 400 401 402 |
# File 'lib/daru_lite/date_time/index.rb', line 393 def slice(first, last) if first.is_a?(Integer) && last.is_a?(Integer) DateTimeIndex.new(to_a[first..last], freq: @offset) else first = Helper.find_date_string_bounds(first)[0] if first.is_a?(String) last = Helper.find_date_string_bounds(last)[1] if last.is_a?(String) slice_between_dates first, last end end |
#subset(*args) ⇒ Object
378 379 380 |
# File 'lib/daru_lite/date_time/index.rb', line 378 def subset(*args) self[*args] end |
#to_a ⇒ Array<DateTime>
Return the DateTimeIndex as an Array of DateTime objects.
406 407 408 409 410 411 412 |
# File 'lib/daru_lite/date_time/index.rb', line 406 def to_a if @offset @data else @data.sort_by(&:last) end.transpose.first || [] end |
#valid?(*args) ⇒ Boolean
382 383 384 385 386 387 |
# File 'lib/daru_lite/date_time/index.rb', line 382 def valid?(*args) self[*args] true rescue IndexError false end |
#year ⇒ Array<Integer>
Returns Array containing year of each index.
498 499 500 501 502 503 504 |
# File 'lib/daru_lite/date_time/index.rb', line 498 %i[year month day hour min sec].each do |meth| define_method(meth) do each_with_object([]) do |d, arr| arr << d.send(meth) end end end |