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 ⇒ 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 ⇒ 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 ⇒ Object
-
#to_a ⇒ Array<DateTime>
Return the DateTimeIndex as an Array of DateTime objects.
- #valid? ⇒ Boolean
-
#year ⇒ Array<Integer>
Array containing year of each index.
Methods inherited from Index
#&, __new__, #add, #at, coerce, #conform, #delete_at, 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.
256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 |
# File 'lib/daru_lite/date_time/index.rb', line 256 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.
230 231 232 |
# File 'lib/daru_lite/date_time/index.rb', line 230 def frequency @frequency end |
#keys ⇒ Object (readonly)
Returns the value of attribute keys.
230 231 232 |
# File 'lib/daru_lite/date_time/index.rb', line 230 def keys @keys end |
#offset ⇒ Object (readonly)
Returns the value of attribute offset.
230 231 232 |
# File 'lib/daru_lite/date_time/index.rb', line 230 def offset @offset end |
#periods ⇒ Object (readonly)
Returns the value of attribute periods.
230 231 232 |
# File 'lib/daru_lite/date_time/index.rb', line 230 def periods @periods end |
Class Method Details
._load(data) ⇒ Object
480 481 482 483 484 |
# File 'lib/daru_lite/date_time/index.rb', line 480 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.
336 337 338 339 340 341 342 343 344 |
# File 'lib/daru_lite/date_time/index.rb', line 336 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
222 223 224 |
# File 'lib/daru_lite/date_time/index.rb', line 222 def self.try_create(source) new(source, freq: :infer) if source && ArrayHelper.array_of?(source, ::DateTime) end |
Instance Method Details
#==(other) ⇒ Object
420 421 422 |
# File 'lib/daru_lite/date_time/index.rb', line 420 def ==(other) to_a == other.to_a end |
#[](*key) ⇒ Object
Retreive a slice or a an individual index number from the index.
350 351 352 353 354 355 356 357 358 359 360 361 362 363 364 365 366 367 368 369 |
# File 'lib/daru_lite/date_time/index.rb', line 350 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:
476 477 478 |
# File 'lib/daru_lite/date_time/index.rb', line 476 def _dump(_depth) Marshal.dump(data: to_a, freq: @offset) end |
#day ⇒ Array<Integer>
Returns Array containing day of each index.
499 500 501 502 503 504 505 |
# File 'lib/daru_lite/date_time/index.rb', line 499 %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
274 275 276 |
# File 'lib/daru_lite/date_time/index.rb', line 274 def dup DaruLite::DateTimeIndex.new(@data.transpose[0], freq: @offset) end |
#each ⇒ Object
226 227 228 |
# File 'lib/daru_lite/date_time/index.rb', line 226 def each(&) to_a.each(&) end |
#empty? ⇒ Boolean
Return true if the DateTimeIndex is empty.
522 523 524 |
# File 'lib/daru_lite/date_time/index.rb', line 522 def empty? @data.empty? end |
#hour ⇒ Array<Integer>
Returns Array containing hour of each index.
499 500 501 502 503 504 505 |
# File 'lib/daru_lite/date_time/index.rb', line 499 %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.
509 510 511 512 513 514 515 516 517 518 519 |
# File 'lib/daru_lite/date_time/index.rb', line 509 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
424 425 426 427 428 429 430 |
# File 'lib/daru_lite/date_time/index.rb', line 424 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.
468 469 470 471 472 473 |
# File 'lib/daru_lite/date_time/index.rb', line 468 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.
499 500 501 502 503 504 505 |
# File 'lib/daru_lite/date_time/index.rb', line 499 %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.
499 500 501 502 503 504 505 |
# File 'lib/daru_lite/date_time/index.rb', line 499 %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 ⇒ Object
371 372 373 374 375 376 377 |
# File 'lib/daru_lite/date_time/index.rb', line 371 def pos(*) # to filled out = self[*] return out if out.is_a? Numeric out.map { |date| self[date] } end |
#sec ⇒ Array<Integer>
Returns Array containing seconds of each index.
499 500 501 502 503 504 505 |
# File 'lib/daru_lite/date_time/index.rb', line 499 %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.
452 453 454 455 456 457 |
# File 'lib/daru_lite/date_time/index.rb', line 452 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.
416 417 418 |
# File 'lib/daru_lite/date_time/index.rb', line 416 def size @periods end |
#slice(first, last) ⇒ Object
Retrive a slice of the index by specifying first and last members of the slice.
394 395 396 397 398 399 400 401 402 403 |
# File 'lib/daru_lite/date_time/index.rb', line 394 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 ⇒ Object
379 380 381 |
# File 'lib/daru_lite/date_time/index.rb', line 379 def subset(*) self[*] end |
#to_a ⇒ Array<DateTime>
Return the DateTimeIndex as an Array of DateTime objects.
407 408 409 410 411 412 413 |
# File 'lib/daru_lite/date_time/index.rb', line 407 def to_a if @offset @data else @data.sort_by(&:last) end.transpose.first || [] end |
#valid? ⇒ Boolean
383 384 385 386 387 388 |
# File 'lib/daru_lite/date_time/index.rb', line 383 def valid?(*) self[*] true rescue IndexError false end |
#year ⇒ Array<Integer>
Returns Array containing year of each index.
499 500 501 502 503 504 505 |
# File 'lib/daru_lite/date_time/index.rb', line 499 %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 |