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<Fixnum>
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<Fixnum>
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<Fixnum>
Array containing minutes of each index.
-
#month ⇒ Array<Fixnum>
Array containing month of each index.
- #pos(*args) ⇒ Object
-
#sec ⇒ Array<Fixnum>
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<Fixnum>
Array containing year of each index.
Methods inherited from Index
#&, __new__, #add, #at, coerce, #conform, inherited, #key, #map, 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.
256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 |
# File 'lib/daru/date_time/index.rb', line 256 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.
230 231 232 |
# File 'lib/daru/date_time/index.rb', line 230 def frequency @frequency end |
#offset ⇒ Object (readonly)
Returns the value of attribute offset.
230 231 232 |
# File 'lib/daru/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/date_time/index.rb', line 230 def periods @periods end |
Class Method Details
._load(data) ⇒ Object
475 476 477 478 479 |
# File 'lib/daru/date_time/index.rb', line 475 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.
335 336 337 338 339 340 341 342 343 |
# File 'lib/daru/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
218 219 220 221 222 223 224 |
# File 'lib/daru/date_time/index.rb', line 218 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
417 418 419 |
# File 'lib/daru/date_time/index.rb', line 417 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 |
# File 'lib/daru/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:
471 472 473 |
# File 'lib/daru/date_time/index.rb', line 471 def _dump(_depth) Marshal.dump(data: to_a, freq: @offset) end |
#day ⇒ Array<Fixnum>
Returns Array containing day of each index.
494 495 496 497 498 499 500 |
# File 'lib/daru/date_time/index.rb', line 494 [: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/date_time/index.rb', line 273 def dup Daru::DateTimeIndex.new(@data.transpose[0], freq: @offset) end |
#each(&block) ⇒ Object
226 227 228 |
# File 'lib/daru/date_time/index.rb', line 226 def each(&block) to_a.each(&block) end |
#empty? ⇒ Boolean
Return true if the DateTimeIndex is empty.
517 518 519 |
# File 'lib/daru/date_time/index.rb', line 517 def empty? @data.empty? end |
#hour ⇒ Array<Fixnum>
Returns Array containing hour of each index.
494 495 496 497 498 499 500 |
# File 'lib/daru/date_time/index.rb', line 494 [: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.
504 505 506 507 508 509 510 511 512 513 514 |
# File 'lib/daru/date_time/index.rb', line 504 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
421 422 423 424 425 |
# File 'lib/daru/date_time/index.rb', line 421 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.
463 464 465 466 467 468 |
# File 'lib/daru/date_time/index.rb', line 463 def lag distance distance.is_a?(Fixnum) && distance < 0 and raise IndexError, "Distance #{distance} cannot be negative" _shift(-distance) end |
#min ⇒ Array<Fixnum>
Returns Array containing minutes of each index.
494 495 496 497 498 499 500 |
# File 'lib/daru/date_time/index.rb', line 494 [: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<Fixnum>
Returns Array containing month of each index.
494 495 496 497 498 499 500 |
# File 'lib/daru/date_time/index.rb', line 494 [: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
369 370 371 372 373 374 |
# File 'lib/daru/date_time/index.rb', line 369 def pos *args # to filled out = self[*args] return out if out.is_a? Numeric out.map { |date| self[date] } end |
#sec ⇒ Array<Fixnum>
Returns Array containing seconds of each index.
494 495 496 497 498 499 500 |
# File 'lib/daru/date_time/index.rb', line 494 [: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.
447 448 449 450 451 452 |
# File 'lib/daru/date_time/index.rb', line 447 def shift distance distance.is_a?(Fixnum) && distance < 0 and raise IndexError, "Distance #{distance} cannot be negative" _shift(distance) end |
#size ⇒ Object
Size of index.
413 414 415 |
# File 'lib/daru/date_time/index.rb', line 413 def size @periods end |
#slice(first, last) ⇒ Object
Retrive a slice of the index by specifying first and last members of the slice.
391 392 393 394 395 396 397 398 399 400 |
# File 'lib/daru/date_time/index.rb', line 391 def slice first, last if first.is_a?(Fixnum) && last.is_a?(Fixnum) 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
376 377 378 |
# File 'lib/daru/date_time/index.rb', line 376 def subset *args self[*args] end |
#to_a ⇒ Array<DateTime>
Return the DateTimeIndex as an Array of DateTime objects.
404 405 406 407 408 409 410 |
# File 'lib/daru/date_time/index.rb', line 404 def to_a if @offset @data else @data.sort_by(&:last) end.transpose.first end |
#valid?(*args) ⇒ Boolean
380 381 382 383 384 385 |
# File 'lib/daru/date_time/index.rb', line 380 def valid? *args self[*args] true rescue IndexError false end |
#year ⇒ Array<Fixnum>
Returns Array containing year of each index.
494 495 496 497 498 499 500 |
# File 'lib/daru/date_time/index.rb', line 494 [: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 |