Class: Daru::DateTimeIndex
- Includes:
- Enumerable
- Defined in:
- lib/daru/date_time/index.rb
Constant Summary collapse
- Helper =
DateTimeIndexHelper
Instance Attribute Summary collapse
-
#frequency ⇒ Object
readonly
Returns the value of attribute frequency.
-
#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, #key, new, #reorder, #|
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 |
# File 'lib/daru/date_time/index.rb', line 255 def initialize data, opts={freq: nil} 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 ? @offset.freq_string : nil @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/date_time/index.rb', line 229 def frequency @frequency end |
#offset ⇒ Object (readonly)
Returns the value of attribute offset.
229 230 231 |
# File 'lib/daru/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/date_time/index.rb', line 229 def periods @periods end |
Class Method Details
._load(data) ⇒ Object
474 475 476 477 478 |
# File 'lib/daru/date_time/index.rb', line 474 def self._load data h = Marshal.load data Daru::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.
334 335 336 337 338 339 340 341 342 |
# File 'lib/daru/date_time/index.rb', line 334 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
217 218 219 220 221 222 223 |
# File 'lib/daru/date_time/index.rb', line 217 def self.try_create(source) if source && ArrayHelper.array_of?(source, ::DateTime) new(source, freq: :infer) else nil end end |
Instance Method Details
#==(other) ⇒ Object
416 417 418 |
# File 'lib/daru/date_time/index.rb', line 416 def == other to_a == other.to_a end |
#[](*key) ⇒ Object
Retreive a slice or a an individual index number from the index.
348 349 350 351 352 353 354 355 356 357 358 359 360 361 362 363 364 365 366 |
# File 'lib/daru/date_time/index.rb', line 348 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:
470 471 472 |
# File 'lib/daru/date_time/index.rb', line 470 def _dump(_depth) Marshal.dump(data: to_a, freq: @offset) end |
#day ⇒ Array<Integer>
Returns Array containing day of each index.
493 494 495 496 497 498 499 |
# File 'lib/daru/date_time/index.rb', line 493 [: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
272 273 274 |
# File 'lib/daru/date_time/index.rb', line 272 def dup Daru::DateTimeIndex.new(@data.transpose[0], freq: @offset) end |
#each(&block) ⇒ Object
225 226 227 |
# File 'lib/daru/date_time/index.rb', line 225 def each(&block) to_a.each(&block) end |
#empty? ⇒ Boolean
Return true if the DateTimeIndex is empty.
516 517 518 |
# File 'lib/daru/date_time/index.rb', line 516 def empty? @data.empty? end |
#hour ⇒ Array<Integer>
Returns Array containing hour of each index.
493 494 495 496 497 498 499 |
# File 'lib/daru/date_time/index.rb', line 493 [: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.
503 504 505 506 507 508 509 510 511 512 513 |
# File 'lib/daru/date_time/index.rb', line 503 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
420 421 422 423 424 |
# File 'lib/daru/date_time/index.rb', line 420 def inspect = [@periods, @frequency ? "frequency=#{@frequency}" : nil].compact.join(', ') "#<#{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.
462 463 464 465 466 467 |
# File 'lib/daru/date_time/index.rb', line 462 def lag distance distance.is_a?(Integer) && distance < 0 and raise IndexError, "Distance #{distance} cannot be negative" _shift(-distance) end |
#min ⇒ Array<Integer>
Returns Array containing minutes of each index.
493 494 495 496 497 498 499 |
# File 'lib/daru/date_time/index.rb', line 493 [: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.
493 494 495 496 497 498 499 |
# File 'lib/daru/date_time/index.rb', line 493 [: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
368 369 370 371 372 373 |
# File 'lib/daru/date_time/index.rb', line 368 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.
493 494 495 496 497 498 499 |
# File 'lib/daru/date_time/index.rb', line 493 [: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.
446 447 448 449 450 451 |
# File 'lib/daru/date_time/index.rb', line 446 def shift distance distance.is_a?(Integer) && distance < 0 and raise IndexError, "Distance #{distance} cannot be negative" _shift(distance) end |
#size ⇒ Object
Size of index.
412 413 414 |
# File 'lib/daru/date_time/index.rb', line 412 def size @periods end |
#slice(first, last) ⇒ Object
Retrive a slice of the index by specifying first and last members of the slice.
390 391 392 393 394 395 396 397 398 399 |
# File 'lib/daru/date_time/index.rb', line 390 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
375 376 377 |
# File 'lib/daru/date_time/index.rb', line 375 def subset *args self[*args] end |
#to_a ⇒ Array<DateTime>
Return the DateTimeIndex as an Array of DateTime objects.
403 404 405 406 407 408 409 |
# File 'lib/daru/date_time/index.rb', line 403 def to_a if @offset @data else @data.sort_by(&:last) end.transpose.first end |
#valid?(*args) ⇒ Boolean
379 380 381 382 383 384 |
# File 'lib/daru/date_time/index.rb', line 379 def valid? *args self[*args] true rescue IndexError false end |
#year ⇒ Array<Integer>
Returns Array containing year of each index.
493 494 495 496 497 498 499 |
# File 'lib/daru/date_time/index.rb', line 493 [: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 |