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.
- #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__, #dup, 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.
250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 |
# File 'lib/daru/date_time/index.rb', line 250 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.
224 225 226 |
# File 'lib/daru/date_time/index.rb', line 224 def frequency @frequency end |
#offset ⇒ Object (readonly)
Returns the value of attribute offset.
224 225 226 |
# File 'lib/daru/date_time/index.rb', line 224 def offset @offset end |
#periods ⇒ Object (readonly)
Returns the value of attribute periods.
224 225 226 |
# File 'lib/daru/date_time/index.rb', line 224 def periods @periods end |
Class Method Details
._load(data) ⇒ Object
504 505 506 507 508 |
# File 'lib/daru/date_time/index.rb', line 504 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.
329 330 331 332 333 334 335 336 337 338 339 |
# File 'lib/daru/date_time/index.rb', line 329 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
427 428 429 |
# File 'lib/daru/date_time/index.rb', line 427 def == other self.to_a == other.to_a end |
#[](*key) ⇒ Object
Retreive a slice or a an individual index number from the index.
345 346 347 348 349 350 351 352 353 354 355 356 357 358 359 360 361 362 363 364 365 366 367 368 369 370 371 372 373 374 375 376 377 |
# File 'lib/daru/date_time/index.rb', line 345 def [] *key helper = DateTimeIndexHelper if key.size == 1 key = key[0] return key if key.is_a?(Numeric) else return slice(*key) end if key.is_a?(Range) first = key.first last = key.last return slice(first, last) if first.is_a?(Fixnum) and last.is_a?(Fixnum) raise ArgumentError, "Keys #{first} and #{last} are out of bounds" if helper.key_out_of_bounds?(first, @data) and 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] else if 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 end slice slice_begin, slice_end end |
#_dump(depth) ⇒ Object
500 501 502 |
# File 'lib/daru/date_time/index.rb', line 500 def _dump depth Marshal.dump({data: self.to_a, freq: @offset}) end |
#day ⇒ Array<Fixnum>
Returns Array containing day of each index.
522 523 524 525 526 527 528 529 |
# File 'lib/daru/date_time/index.rb', line 522 [:year, :month, :day, :hour, :min, :sec].each do |meth| define_method(meth) do self.inject([]) do |arr, d| arr << d.send(meth) arr end end end |
#each(&block) ⇒ Object
220 221 222 |
# File 'lib/daru/date_time/index.rb', line 220 def each(&block) to_a.each(&block) end |
#empty? ⇒ Boolean
Return true if the DateTimeIndex is empty.
546 547 548 |
# File 'lib/daru/date_time/index.rb', line 546 def empty? @data.empty? end |
#hour ⇒ Array<Fixnum>
Returns Array containing hour of each index.
522 523 524 525 526 527 528 529 |
# File 'lib/daru/date_time/index.rb', line 522 [:year, :month, :day, :hour, :min, :sec].each do |meth| define_method(meth) do self.inject([]) do |arr, d| arr << d.send(meth) arr 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.
533 534 535 536 537 538 539 540 541 542 543 |
# File 'lib/daru/date_time/index.rb', line 533 def include? date_time return false if !(date_time.is_a?(String) or 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 } result[0] == date_time end |
#inspect ⇒ Object
431 432 433 434 435 436 437 |
# File 'lib/daru/date_time/index.rb', line 431 def inspect string = "#<DateTimeIndex:" + self.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.
484 485 486 487 488 489 490 491 492 493 494 495 496 497 498 |
# File 'lib/daru/date_time/index.rb', line 484 def lag distance if distance.is_a?(Fixnum) raise IndexError, "Distance #{distance} cannot be negative" if distance < 0 if @offset start = @data[0][0] distance.times { start = @offset - start } return DateTimeIndex.date_range( :start => start, :periods => @periods, freq: @offset) else raise IndexError, "To lag non-freq date time index pass an offset." end else DateTimeIndex.new(self.to_a.map { |e| distance - e }, freq: :infer) end end |
#min ⇒ Array<Fixnum>
Returns Array containing minutes of each index.
522 523 524 525 526 527 528 529 |
# File 'lib/daru/date_time/index.rb', line 522 [:year, :month, :day, :hour, :min, :sec].each do |meth| define_method(meth) do self.inject([]) do |arr, d| arr << d.send(meth) arr end end end |
#month ⇒ Array<Fixnum>
Returns Array containing month of each index.
522 523 524 525 526 527 528 529 |
# File 'lib/daru/date_time/index.rb', line 522 [:year, :month, :day, :hour, :min, :sec].each do |meth| define_method(meth) do self.inject([]) do |arr, d| arr << d.send(meth) arr end end end |
#sec ⇒ Array<Fixnum>
Returns Array containing seconds of each index.
522 523 524 525 526 527 528 529 |
# File 'lib/daru/date_time/index.rb', line 522 [:year, :month, :day, :hour, :min, :sec].each do |meth| define_method(meth) do self.inject([]) do |arr, d| arr << d.send(meth) arr 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.
459 460 461 462 463 464 465 466 467 468 469 470 471 472 473 |
# File 'lib/daru/date_time/index.rb', line 459 def shift distance if distance.is_a?(Fixnum) raise IndexError, "Distance #{distance} cannot be negative" if distance < 0 if @offset start = @data[0][0] distance.times { start = @offset + start } return DateTimeIndex.date_range( :start => start, :periods => @periods, freq: @offset) else raise IndexError, "To shift non-freq date time index pass an offset." end else # its a Daru::Offset/DateOffset DateTimeIndex.new(self.to_a.map { |e| distance + e }, freq: :infer) end end |
#size ⇒ Object
Size of index.
423 424 425 |
# File 'lib/daru/date_time/index.rb', line 423 def size @periods end |
#slice(first, last) ⇒ Object
Retrive a slice of the index by specifying first and last members of the slice.
383 384 385 386 387 388 389 390 391 392 393 394 395 396 397 398 399 400 401 402 403 404 405 406 407 408 409 410 411 412 413 |
# File 'lib/daru/date_time/index.rb', line 383 def slice first, last helper = DateTimeIndexHelper if first.is_a?(String) and last.is_a?(String) self[first..last] elsif first.is_a?(Fixnum) and last.is_a?(Fixnum) DateTimeIndex.new(self.to_a[first..last], freq: @offset) else first_dt = first.is_a?(String) ? helper.find_date_string_bounds(first)[0] : first last_dt = last.is_a?(String) ? helper.find_date_string_bounds(last)[1] : last 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.
417 418 419 420 |
# File 'lib/daru/date_time/index.rb', line 417 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.
522 523 524 525 526 527 528 529 |
# File 'lib/daru/date_time/index.rb', line 522 [:year, :month, :day, :hour, :min, :sec].each do |meth| define_method(meth) do self.inject([]) do |arr, d| arr << d.send(meth) arr end end end |