Class: Daru::DateTimeIndex
- Includes:
- Enumerable
- Defined in:
- lib/daru/date_time/index.rb
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.
Instance Method Summary collapse
- #==(other) ⇒ Object
-
#[](*key) ⇒ Object
Retreive a slice or a an individual index number from the index.
- #_dump(_depth) ⇒ Object
-
#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(*args) ⇒ 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.
-
#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.
-
#to_a ⇒ Array<DateTime>
Return the DateTimeIndex as an Array of DateTime objects.
-
#year ⇒ Array<Fixnum>
Array containing year of each index.
Methods inherited from Index
#&, __new__, #conform, inherited, #key, #map, new, #|
Constructor Details
#initialize(*args) ⇒ 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.
258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 274 275 276 277 278 |
# File 'lib/daru/date_time/index.rb', line 258 def initialize *args helper = DateTimeIndexHelper data = args[0] opts = args[1] || {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.zip(Array.new(data.size) { |i| i }) @data.sort_by! { |d| d[0] } if @offset.nil? @periods = data.size end |
Instance Attribute Details
#frequency ⇒ Object (readonly)
Returns the value of attribute frequency.
232 233 234 |
# File 'lib/daru/date_time/index.rb', line 232 def frequency @frequency end |
#offset ⇒ Object (readonly)
Returns the value of attribute offset.
232 233 234 |
# File 'lib/daru/date_time/index.rb', line 232 def offset @offset end |
#periods ⇒ Object (readonly)
Returns the value of attribute periods.
232 233 234 |
# File 'lib/daru/date_time/index.rb', line 232 def periods @periods end |
Class Method Details
._load(data) ⇒ Object
517 518 519 520 521 |
# File 'lib/daru/date_time/index.rb', line 517 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.
343 344 345 346 347 348 349 350 351 352 353 |
# File 'lib/daru/date_time/index.rb', line 343 def self.date_range opts={} helper = DateTimeIndexHelper start = helper.start_date opts[:start] en = helper.end_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 |
Instance Method Details
#==(other) ⇒ Object
446 447 448 |
# File 'lib/daru/date_time/index.rb', line 446 def == other to_a == other.to_a end |
#[](*key) ⇒ Object
Retreive a slice or a an individual index number from the index.
359 360 361 362 363 364 365 366 367 368 369 370 371 372 373 374 375 376 377 378 379 380 381 382 383 384 385 386 387 |
# File 'lib/daru/date_time/index.rb', line 359 def [] *key helper = DateTimeIndexHelper return slice(*key) if key.size != 1 key = key[0] return key if key.is_a?(Numeric) if key.is_a?(Range) first = key.first last = key.last return slice(first, last) if first.is_a?(Fixnum) && last.is_a?(Fixnum) raise ArgumentError, "Keys #{first} and #{last} are out of bounds" if helper.key_out_of_bounds?(first, @data) && helper.key_out_of_bounds?(last, @data) slice_begin = helper.find_date_string_bounds(first)[0] slice_end = helper.find_date_string_bounds(last)[1] elsif key.is_a?(DateTime) return helper.find_index_of_date(@data, key) else raise ArgumentError, "Key #{key} is out of bounds" if helper.key_out_of_bounds?(key, @data) slice_begin, slice_end = helper.find_date_string_bounds key end slice slice_begin, slice_end end |
#_dump(_depth) ⇒ Object
513 514 515 |
# File 'lib/daru/date_time/index.rb', line 513 def _dump(_depth) Marshal.dump(data: to_a, freq: @offset) end |
#day ⇒ Array<Fixnum>
Returns Array containing day of each index.
535 536 537 538 539 540 541 |
# File 'lib/daru/date_time/index.rb', line 535 [: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
281 282 283 |
# File 'lib/daru/date_time/index.rb', line 281 def dup Daru::DateTimeIndex.new(@data.transpose[0], freq: @offset) end |
#each(&block) ⇒ Object
228 229 230 |
# File 'lib/daru/date_time/index.rb', line 228 def each(&block) to_a.each(&block) end |
#empty? ⇒ Boolean
Return true if the DateTimeIndex is empty.
559 560 561 |
# File 'lib/daru/date_time/index.rb', line 559 def empty? @data.empty? end |
#hour ⇒ Array<Fixnum>
Returns Array containing hour of each index.
535 536 537 538 539 540 541 |
# File 'lib/daru/date_time/index.rb', line 535 [: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.
545 546 547 548 549 550 551 552 553 554 555 556 |
# File 'lib/daru/date_time/index.rb', line 545 def include? date_time return false unless date_time.is_a?(String) || date_time.is_a?(DateTime) helper = DateTimeIndexHelper 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 } return false if result.nil? result[0] == date_time end |
#inspect ⇒ Object
450 451 452 453 454 455 456 |
# File 'lib/daru/date_time/index.rb', line 450 def inspect string = '#<DateTimeIndex:' + object_id.to_s + ' offset=' + (@offset ? @offset.freq_string : 'nil') + ' periods=' + @periods.to_s + ' data=[' + @data.first[0].to_s + '...' + @data.last[0].to_s + ']'+ '>' string 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.
500 501 502 503 504 505 506 507 508 509 510 511 |
# File 'lib/daru/date_time/index.rb', line 500 def lag distance if distance.is_a?(Fixnum) raise IndexError, "Distance #{distance} cannot be negative" if distance < 0 raise IndexError, 'To lag non-freq date time index pass an offset.' unless @offset start = @data[0][0] distance.times { start = @offset - start } DateTimeIndex.date_range(start: start, periods: @periods, freq: @offset) else DateTimeIndex.new(to_a.map { |e| distance - e }, freq: :infer) end end |
#min ⇒ Array<Fixnum>
Returns Array containing minutes of each index.
535 536 537 538 539 540 541 |
# File 'lib/daru/date_time/index.rb', line 535 [: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.
535 536 537 538 539 540 541 |
# File 'lib/daru/date_time/index.rb', line 535 [: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 |
#sec ⇒ Array<Fixnum>
Returns Array containing seconds of each index.
535 536 537 538 539 540 541 |
# File 'lib/daru/date_time/index.rb', line 535 [: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.
478 479 480 481 482 483 484 485 486 487 488 489 |
# File 'lib/daru/date_time/index.rb', line 478 def shift distance if distance.is_a?(Fixnum) raise IndexError, "Distance #{distance} cannot be negative" if distance < 0 raise IndexError, 'To shift non-freq date time index pass an offset.' unless @offset start = @data[0][0] distance.times { start = @offset + start } DateTimeIndex.date_range(start: start, periods: @periods, freq: @offset) else # its a Daru::Offset/DateOffset DateTimeIndex.new(to_a.map { |e| distance + e }, freq: :infer) end end |
#size ⇒ Object
Size of index.
442 443 444 |
# File 'lib/daru/date_time/index.rb', line 442 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 403 404 405 406 407 408 409 410 411 412 413 414 415 416 417 418 419 420 421 422 423 424 425 426 427 428 429 430 431 432 |
# File 'lib/daru/date_time/index.rb', line 393 def slice first, last helper = DateTimeIndexHelper if first.is_a?(String) && last.is_a?(String) self[first..last] elsif first.is_a?(Fixnum) && last.is_a?(Fixnum) DateTimeIndex.new(to_a[first..last], freq: @offset) else first_dt = if first.is_a?(String) helper.find_date_string_bounds(first)[0] else first end last_dt = if last.is_a?(String) helper.find_date_string_bounds(last)[1] else last end start = @data.bsearch { |d| d[0] >= first_dt } after_en = @data.bsearch { |d| d[0] > last_dt } result = if @offset en = after_en ? @data[after_en[1] - 1] : @data.last return start[1] if start == en DateTimeIndex.date_range start: start[0], end: en[0], freq: @offset else st = @data.index(start) en = after_en ? @data.index(after_en) - 1 : helper.last_date(@data)[1] return start[1] if st == en DateTimeIndex.new(@data[st..en].transpose[0]) end result end end |
#to_a ⇒ Array<DateTime>
Return the DateTimeIndex as an Array of DateTime objects.
436 437 438 439 |
# File 'lib/daru/date_time/index.rb', line 436 def to_a return @data.sort_by { |d| d[1] }.transpose[0] unless @offset @data.transpose[0] end |
#year ⇒ Array<Fixnum>
Returns Array containing year of each index.
535 536 537 538 539 540 541 |
# File 'lib/daru/date_time/index.rb', line 535 [: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 |