daru 0.1.2 → 0.1.3

Sign up to get free protection for your applications and to get access to all the features.
Files changed (49) hide show
  1. checksums.yaml +4 -4
  2. data/.gitignore +2 -0
  3. data/.rubocop.yml +99 -0
  4. data/.rubocop_todo.yml +44 -0
  5. data/.travis.yml +3 -1
  6. data/CONTRIBUTING.md +5 -1
  7. data/History.md +43 -0
  8. data/README.md +3 -4
  9. data/benchmarks/duplicating.rb +45 -0
  10. data/benchmarks/group_by.rb +7 -7
  11. data/benchmarks/joining.rb +52 -0
  12. data/benchmarks/sorting.rb +9 -2
  13. data/benchmarks/statistics.rb +39 -0
  14. data/daru.gemspec +4 -4
  15. data/lib/daru.rb +9 -9
  16. data/lib/daru/accessors/array_wrapper.rb +15 -11
  17. data/lib/daru/accessors/dataframe_by_row.rb +1 -1
  18. data/lib/daru/accessors/gsl_wrapper.rb +30 -19
  19. data/lib/daru/accessors/mdarray_wrapper.rb +1 -3
  20. data/lib/daru/accessors/nmatrix_wrapper.rb +15 -15
  21. data/lib/daru/core/group_by.rb +69 -16
  22. data/lib/daru/core/merge.rb +135 -151
  23. data/lib/daru/core/query.rb +9 -30
  24. data/lib/daru/dataframe.rb +476 -439
  25. data/lib/daru/date_time/index.rb +150 -137
  26. data/lib/daru/date_time/offsets.rb +45 -41
  27. data/lib/daru/extensions/rserve.rb +4 -4
  28. data/lib/daru/index.rb +88 -64
  29. data/lib/daru/io/io.rb +33 -34
  30. data/lib/daru/io/sql_data_source.rb +11 -11
  31. data/lib/daru/maths/arithmetic/dataframe.rb +19 -19
  32. data/lib/daru/maths/arithmetic/vector.rb +9 -14
  33. data/lib/daru/maths/statistics/dataframe.rb +89 -61
  34. data/lib/daru/maths/statistics/vector.rb +226 -97
  35. data/lib/daru/monkeys.rb +23 -30
  36. data/lib/daru/plotting/dataframe.rb +27 -28
  37. data/lib/daru/plotting/vector.rb +12 -13
  38. data/lib/daru/vector.rb +221 -330
  39. data/lib/daru/version.rb +2 -2
  40. data/spec/core/group_by_spec.rb +16 -0
  41. data/spec/core/merge_spec.rb +30 -14
  42. data/spec/dataframe_spec.rb +268 -14
  43. data/spec/index_spec.rb +23 -5
  44. data/spec/io/io_spec.rb +37 -16
  45. data/spec/math/statistics/dataframe_spec.rb +40 -8
  46. data/spec/math/statistics/vector_spec.rb +135 -10
  47. data/spec/monkeys_spec.rb +3 -3
  48. data/spec/vector_spec.rb +157 -25
  49. metadata +41 -21
@@ -15,34 +15,34 @@ module Daru
15
15
  'YEAR' => Daru::Offsets::Year,
16
16
  'YB' => Daru::Offsets::YearBegin,
17
17
  'YE' => Daru::Offsets::YearEnd
18
- }
18
+ }.freeze
19
19
 
20
20
  TIME_INTERVALS = {
21
21
  Rational(1,1) => Daru::Offsets::Day,
22
22
  Rational(1,24) => Daru::Offsets::Hour,
23
23
  Rational(1,1440) => Daru::Offsets::Minute,
24
- Rational(1,86400) => Daru::Offsets::Second
25
- }
24
+ Rational(1,86_400) => Daru::Offsets::Second
25
+ }.freeze
26
26
 
27
27
  # Generates a Daru::DateOffset object for generic offsets or one of the
28
28
  # specialized classed within Daru::Offsets depending on the 'frequency'
29
29
  # string.
30
30
  def offset_from_frequency frequency
31
31
  frequency = 'D' if frequency.nil?
32
- return frequency if frequency.kind_of?(Daru::DateOffset)
32
+ return frequency if frequency.is_a?(Daru::DateOffset)
33
33
 
34
34
  matched = /([0-9]*)(MONTH|YEAR|S|H|MB|ME|M|D|W|YB|YE)/.match(frequency)
35
- raise ArgumentError,
35
+ raise ArgumentError,
36
36
  "Invalid frequency string #{frequency}" if matched.nil?
37
37
 
38
- n = matched[1] == "" ? 1 : matched[1].to_i
38
+ n = matched[1] == '' ? 1 : matched[1].to_i
39
39
  offset_string = matched[2]
40
40
  offset_klass = OFFSETS_HASH[offset_string]
41
41
 
42
42
  raise ArgumentError,
43
43
  "Cannont interpret offset #{offset_string}" if offset_klass.nil?
44
44
 
45
- if offset_string.match(/W/)
45
+ if offset_string =~ /W/
46
46
  day = Regexp.new(Daru::DAYS_OF_WEEK.keys.join('|')).match(frequency).to_s
47
47
  return offset_klass.new(n, weekday: Daru::DAYS_OF_WEEK[day])
48
48
  end
@@ -51,18 +51,24 @@ module Daru
51
51
  end
52
52
 
53
53
  def start_date start
54
- start.is_a?(String) ? date_time_from(
55
- start, determine_date_precision_of(start)) : start
54
+ if start.is_a?(String)
55
+ date_time_from(start, determine_date_precision_of(start))
56
+ else
57
+ start
58
+ end
56
59
  end
57
60
 
58
61
  def end_date en
59
- en.is_a?(String) ? date_time_from(
60
- en, determine_date_precision_of(en)) : en
62
+ if en.is_a?(String)
63
+ date_time_from(en, determine_date_precision_of(en))
64
+ else
65
+ en
66
+ end
61
67
  end
62
68
 
63
69
  def begin_from_offset? offset, start
64
- if offset.kind_of?(Daru::Offsets::Tick) or
65
- (offset.respond_to?(:on_offset?) and offset.on_offset?(start))
70
+ if offset.is_a?(Daru::Offsets::Tick) ||
71
+ (offset.respond_to?(:on_offset?) && offset.on_offset?(start))
66
72
  true
67
73
  else
68
74
  false
@@ -80,7 +86,7 @@ module Daru
80
86
  new_date = offset + new_date
81
87
  end
82
88
  else
83
- periods.times do |i|
89
+ periods.times do
84
90
  data << new_date
85
91
  new_date = offset + new_date
86
92
  end
@@ -90,16 +96,16 @@ module Daru
90
96
  end
91
97
 
92
98
  def verify_start_and_end start, en
93
- raise ArgumentError, "Start and end cannot be the same" if start == en
94
- raise ArgumentError, "Start must be lesser than end" if start > en
95
- raise ArgumentError,
96
- "Only same time zones are allowed" if start.zone != en.zone
99
+ raise ArgumentError, 'Start and end cannot be the same' if start == en
100
+ raise ArgumentError, 'Start must be lesser than end' if start > en
101
+ raise ArgumentError,
102
+ 'Only same time zones are allowed' if start.zone != en.zone
97
103
  end
98
104
 
99
105
  def infer_offset data
100
106
  possible_freq = data[1] - data[0]
101
107
  inferred = true
102
- data.each_cons(2) do |d|
108
+ data.each_cons(2) do |d|
103
109
  if d[1] - d[0] != possible_freq
104
110
  inferred = false
105
111
  break
@@ -107,7 +113,7 @@ module Daru
107
113
  end
108
114
 
109
115
  if inferred
110
- TIME_INTERVALS[possible_freq].new
116
+ TIME_INTERVALS[possible_freq].new
111
117
  else
112
118
  nil
113
119
  end
@@ -115,8 +121,9 @@ module Daru
115
121
 
116
122
  def find_index_of_date data, date_time
117
123
  searched = data.bsearch { |d| d[0] >= date_time }
118
- (!searched.nil? and searched[0] == date_time) ? searched[1] :
119
- raise(ArgumentError, "Cannot find #{date_time}")
124
+ raise(ArgumentError, "Cannot find #{date_time}") if searched.nil? || searched[0] != date_time
125
+
126
+ searched[1]
120
127
  end
121
128
 
122
129
  def find_date_string_bounds date_string
@@ -131,8 +138,9 @@ module Daru
131
138
  DateTime.new(date_string.gsub(/[^0-9]/, '').to_i)
132
139
  when :month
133
140
  DateTime.new(
134
- date_string.match(/\d\d\d\d/).to_s.to_i,
135
- date_string.match(/\-\d?\d/).to_s.gsub("-",'').to_i)
141
+ date_string.match(/\d\d\d\d/).to_s.to_i,
142
+ date_string.match(/\-\d?\d/).to_s.delete('-').to_i
143
+ )
136
144
  else
137
145
  DateTime.parse date_string
138
146
  end
@@ -161,7 +169,7 @@ module Daru
161
169
  case date_precision
162
170
  when :year
163
171
  [
164
- date_time,
172
+ date_time,
165
173
  DateTime.new(date_time.year,12,31,23,59,59)
166
174
  ]
167
175
  when :month
@@ -178,17 +186,17 @@ module Daru
178
186
  when :hour
179
187
  [
180
188
  date_time,
181
- DateTime.new(date_time.year, date_time.month, date_time.day,
182
- date_time.hour,59,59)
189
+ DateTime.new(date_time.year, date_time.month, date_time.day,
190
+ date_time.hour,59,59)
183
191
  ]
184
192
  when :min
185
193
  [
186
194
  date_time,
187
- DateTime.new(date_time.year, date_time.month, date_time.day,
195
+ DateTime.new(date_time.year, date_time.month, date_time.day,
188
196
  date_time.hour, date_time.min, 59)
189
- ]
197
+ ]
190
198
  else # second or when precision is same as offset
191
- [ date_time, date_time ]
199
+ [date_time, date_time]
192
200
  end
193
201
  end
194
202
 
@@ -205,10 +213,10 @@ module Daru
205
213
  date_time = date_time_from key, precision
206
214
  case precision
207
215
  when :year
208
- date_time.year < data[0][0].year or date_time.year > data[-1][0].year
216
+ date_time.year < data[0][0].year || date_time.year > data[-1][0].year
209
217
  when :month
210
- (date_time.year < data[0][0].year and date_time.month < data[0][0].month) or
211
- (date_time.year > data[-1][0].year and date_time.month > data[-1][0].month)
218
+ (date_time.year < data[0][0].year && date_time.month < data[0][0].month) ||
219
+ (date_time.year > data[-1][0].year and date_time.month > data[-1][0].month)
212
220
  end
213
221
  end
214
222
  end
@@ -227,7 +235,7 @@ module Daru
227
235
  # should be used for creating DateTimeIndex by directly passing in DateTime
228
236
  # objects or date-like strings, typically in cases where values with frequency
229
237
  # are not needed.
230
- #
238
+ #
231
239
  # @param [Array<String>, Array<DateTime>] data Array of date-like Strings or
232
240
  # actual DateTime objects for creating the DateTimeIndex.
233
241
  # @param [Hash] opts Hash of options for configuring index.
@@ -235,16 +243,16 @@ module Daru
235
243
  # Option for specifying the frequency of data, if applicable. If `:infer` is
236
244
  # passed to this option, daru will try to infer the frequency of the data
237
245
  # by itself.
238
- #
246
+ #
239
247
  # @example Usage of DateTimeIndex constructor
240
248
  # index = Daru::DateTimeIndex.new(
241
- # [DateTime.new(2012,4,5), DateTime.new(2012,4,6),
249
+ # [DateTime.new(2012,4,5), DateTime.new(2012,4,6),
242
250
  # DateTime.new(2012,4,7), DateTime.new(2012,4,8)])
243
251
  # #=>#<DateTimeIndex:84232240 offset=nil periods=4 data=[2012-04-05T00:00:00+00:00...2012-04-08T00:00:00+00:00]>
244
252
  #
245
253
  # index = Daru::DateTimeIndex.new([
246
- # DateTime.new(2012,4,5), DateTime.new(2012,4,6), DateTime.new(2012,4,7),
247
- # DateTime.new(2012,4,8), DateTime.new(2012,4,9), DateTime.new(2012,4,10),
254
+ # DateTime.new(2012,4,5), DateTime.new(2012,4,6), DateTime.new(2012,4,7),
255
+ # DateTime.new(2012,4,8), DateTime.new(2012,4,9), DateTime.new(2012,4,10),
248
256
  # DateTime.new(2012,4,11), DateTime.new(2012,4,12)], freq: :infer)
249
257
  # #=>#<DateTimeIndex:84198340 offset=D periods=8 data=[2012-04-05T00:00:00+00:00...2012-04-12T00:00:00+00:00]>
250
258
  def initialize *args
@@ -255,43 +263,49 @@ module Daru
255
263
 
256
264
  helper.possibly_convert_to_date_time data
257
265
 
258
- @offset =
259
- case opts[:freq]
260
- when :infer then helper.infer_offset(data)
261
- when nil then nil
262
- else helper.offset_from_frequency(opts[:freq])
263
- end
266
+ @offset =
267
+ case opts[:freq]
268
+ when :infer then helper.infer_offset(data)
269
+ when nil then nil
270
+ else helper.offset_from_frequency(opts[:freq])
271
+ end
264
272
 
265
273
  @frequency = @offset ? @offset.freq_string : nil
266
274
  @data = data.zip(Array.new(data.size) { |i| i })
267
275
  @data.sort_by! { |d| d[0] } if @offset.nil?
268
- @periods = data.size
276
+
277
+ @periods = data.size
278
+ end
279
+
280
+ # Custom dup method for DateTimeIndex
281
+ def dup
282
+ Daru::DateTimeIndex.new(@data.transpose[0], freq: @offset)
269
283
  end
270
284
 
271
285
  # Create a date range by specifying the start, end, periods and frequency
272
286
  # of the data.
273
- #
287
+ #
274
288
  # @param [Hash] opts Options hash to create the date range with
275
- # @option opts [String, DateTime] :start A DateTime object or date-like
289
+ # @option opts [String, DateTime] :start A DateTime object or date-like
276
290
  # string that defines the start of the date range.
277
- # @option opts [String, DateTime] :end A DateTime object or date-like string
291
+ # @option opts [String, DateTime] :end A DateTime object or date-like string
278
292
  # that defines the end of the date range.
279
- # @option opts [String, Daru::DateOffset, Daru::Offsets::*] :freq ('D') The interval
280
- # between each date in the index. This can either be a string specifying
293
+ # @option opts [String, Daru::DateOffset, Daru::Offsets::*] :freq ('D') The interval
294
+ # between each date in the index. This can either be a string specifying
281
295
  # the frequency (i.e. one of the frequency aliases) or an offset object.
282
- # @option opts [Fixnum] :periods The number of periods that should go into
296
+ # @option opts [Fixnum] :periods The number of periods that should go into
283
297
  # this index. Takes precedence over `:end`.
284
298
  # @return [DateTimeIndex] DateTimeIndex object of the specified parameters.
285
299
  #
286
300
  # == Notes
287
301
  #
288
- # If you specify :start and :end options as strings, they can be complete or
289
- # partial dates and daru will intelligently infer the date from the string
290
- # directly. However, note that the date-like string must be in the format
291
- # `YYYY-MM-DD HH:MM:SS`.
302
+ # If you specify :start and :end options as strings, they can be complete or
303
+ # partial dates and daru will intelligently infer the date from the string
304
+ # directly. However, note that the date-like string must be in the format
305
+ # `YYYY-MM-DD HH:MM:SS`.
292
306
  #
293
307
  # The string aliases supported by the :freq option are as follows:
294
- #
308
+ #
295
309
  # * 'S' - seconds
296
310
  # * 'M' - minutes
297
311
  # * 'H' - hours
@@ -310,7 +324,7 @@ module Daru
310
324
  # * 'ME' - month end
311
325
  # * 'YB' - year begin
312
326
  # * 'YE' - year end
313
- #
327
+ #
314
328
  # Multiples of these can also be specified. For example '2S' for 2 seconds
315
329
  # or '2ME' for two month end offsets.
316
330
  #
@@ -319,7 +333,7 @@ module Daru
319
333
  #
320
334
  # @example Creating date ranges
321
335
  # Daru::DateTimeIndex.date_range(
322
- # :start => DateTime.new(2014,5,1),
336
+ # :start => DateTime.new(2014,5,1),
323
337
  # :end => DateTime.new(2014,5,2), :freq => '6H')
324
338
  # #=>#<DateTimeIndex:83600130 offset=H periods=5 data=[2014-05-01T00:00:00+00:00...2014-05-02T00:00:00+00:00]>
325
339
  #
@@ -335,42 +349,38 @@ module Daru
335
349
  offset = helper.offset_from_frequency opts[:freq]
336
350
  data = helper.generate_data start, en, offset, opts[:periods]
337
351
 
338
- DateTimeIndex.new(data, :freq => offset)
352
+ DateTimeIndex.new(data, freq: offset)
339
353
  end
340
354
 
341
355
  # Retreive a slice or a an individual index number from the index.
342
356
  #
343
- # @param [String, DateTime] Specify a date partially (as a String) or
357
+ # @param [String, DateTime] Specify a date partially (as a String) or
344
358
  # completely to retrieve.
345
359
  def [] *key
346
360
  helper = DateTimeIndexHelper
347
- if key.size == 1
348
- key = key[0]
349
- return key if key.is_a?(Numeric)
350
- else
351
- return slice(*key)
352
- end
361
+
362
+ return slice(*key) if key.size != 1
363
+ key = key[0]
364
+ return key if key.is_a?(Numeric)
353
365
 
354
366
  if key.is_a?(Range)
355
367
  first = key.first
356
368
  last = key.last
357
- return slice(first, last) if
358
- first.is_a?(Fixnum) and last.is_a?(Fixnum)
369
+ return slice(first, last) if
370
+ first.is_a?(Fixnum) && last.is_a?(Fixnum)
359
371
 
360
- raise ArgumentError, "Keys #{first} and #{last} are out of bounds" if
361
- helper.key_out_of_bounds?(first, @data) and helper.key_out_of_bounds?(last, @data)
372
+ raise ArgumentError, "Keys #{first} and #{last} are out of bounds" if
373
+ helper.key_out_of_bounds?(first, @data) && helper.key_out_of_bounds?(last, @data)
362
374
 
363
375
  slice_begin = helper.find_date_string_bounds(first)[0]
364
376
  slice_end = helper.find_date_string_bounds(last)[1]
377
+ elsif key.is_a?(DateTime)
378
+ return helper.find_index_of_date(@data, key)
365
379
  else
366
- if key.is_a?(DateTime)
367
- return helper.find_index_of_date(@data, key)
368
- else
369
- raise ArgumentError, "Key #{key} is out of bounds" if
370
- helper.key_out_of_bounds?(key, @data)
380
+ raise ArgumentError, "Key #{key} is out of bounds" if
381
+ helper.key_out_of_bounds?(key, @data)
371
382
 
372
- slice_begin, slice_end = helper.find_date_string_bounds key
373
- end
383
+ slice_begin, slice_end = helper.find_date_string_bounds key
374
384
  end
375
385
 
376
386
  slice slice_begin, slice_end
@@ -383,33 +393,42 @@ module Daru
383
393
  def slice first, last
384
394
  helper = DateTimeIndexHelper
385
395
 
386
- if first.is_a?(String) and last.is_a?(String)
396
+ if first.is_a?(String) && last.is_a?(String)
387
397
  self[first..last]
388
- elsif first.is_a?(Fixnum) and last.is_a?(Fixnum)
389
- DateTimeIndex.new(self.to_a[first..last], freq: @offset)
398
+ elsif first.is_a?(Fixnum) && last.is_a?(Fixnum)
399
+ DateTimeIndex.new(to_a[first..last], freq: @offset)
390
400
  else
391
- first_dt = first.is_a?(String) ?
392
- helper.find_date_string_bounds(first)[0] : first
393
- last_dt = last.is_a?(String) ?
394
- helper.find_date_string_bounds(last)[1] : last
401
+ first_dt =
402
+ if first.is_a?(String)
403
+ helper.find_date_string_bounds(first)[0]
404
+ else
405
+ first
406
+ end
407
+
408
+ last_dt =
409
+ if last.is_a?(String)
410
+ helper.find_date_string_bounds(last)[1]
411
+ else
412
+ last
413
+ end
395
414
 
396
415
  start = @data.bsearch { |d| d[0] >= first_dt }
397
416
  after_en = @data.bsearch { |d| d[0] > last_dt }
398
417
 
399
418
  result =
400
- if @offset
401
- en = after_en ? @data[after_en[1] - 1] : @data.last
402
- return start[1] if start == en
403
- DateTimeIndex.date_range :start => start[0], :end => en[0], freq: @offset
404
- else
405
- st = @data.index(start)
406
- en = after_en ? @data.index(after_en) - 1 : helper.last_date(@data)[1]
407
- return start[1] if st == en
408
- DateTimeIndex.new(@data[st..en].transpose[0])
409
- end
419
+ if @offset
420
+ en = after_en ? @data[after_en[1] - 1] : @data.last
421
+ return start[1] if start == en
422
+ DateTimeIndex.date_range start: start[0], end: en[0], freq: @offset
423
+ else
424
+ st = @data.index(start)
425
+ en = after_en ? @data.index(after_en) - 1 : helper.last_date(@data)[1]
426
+ return start[1] if st == en
427
+ DateTimeIndex.new(@data[st..en].transpose[0])
428
+ end
410
429
 
411
430
  result
412
- end
431
+ end
413
432
  end
414
433
 
415
434
  # Return the DateTimeIndex as an Array of DateTime objects.
@@ -425,80 +444,74 @@ module Daru
425
444
  end
426
445
 
427
446
  def == other
428
- self.to_a == other.to_a
447
+ to_a == other.to_a
429
448
  end
430
449
 
431
450
  def inspect
432
- string = "#<DateTimeIndex:" + self.object_id.to_s + " offset=" +
433
- (@offset ? @offset.freq_string : 'nil') + ' periods=' + @periods.to_s +
434
- " data=[" + @data.first[0].to_s + "..." + @data.last[0].to_s + ']'+ '>'
451
+ string = '#<DateTimeIndex:' + object_id.to_s + ' offset=' +
452
+ (@offset ? @offset.freq_string : 'nil') + ' periods=' + @periods.to_s +
453
+ ' data=[' + @data.first[0].to_s + '...' + @data.last[0].to_s + ']'+ '>'
435
454
 
436
455
  string
437
456
  end
438
457
 
439
458
  # Shift all dates in the index by a positive number in the future. The dates
440
459
  # are shifted by the same amount as that specified in the offset.
441
- #
442
- # @param [Fixnum, Daru::DateOffset, Daru::Offsets::*] distance Distance by
443
- # which each date should be shifted. Passing an offset object to #shift
444
- # will offset each data point by the offset value. Passing a positive
445
- # integer will offset each data point by the same offset that it was
460
+ #
461
+ # @param [Fixnum, Daru::DateOffset, Daru::Offsets::*] distance Distance by
462
+ # which each date should be shifted. Passing an offset object to #shift
463
+ # will offset each data point by the offset value. Passing a positive
464
+ # integer will offset each data point by the same offset that it was
446
465
  # created with.
447
466
  # @return [DateTimeIndex] Returns a new, shifted DateTimeIndex object.
448
467
  # @example Using the shift method
449
468
  # index = Daru::DateTimeIndex.date_range(
450
469
  # :start => '2012', :periods => 10, :freq => 'YEAR')
451
- #
470
+ #
452
471
  # # Passing a offset to shift
453
472
  # index.shift(Daru::Offsets::Hour.new(3))
454
473
  # #=>#<DateTimeIndex:84038960 offset=nil periods=10 data=[2012-01-01T03:00:00+00:00...2021-01-01T03:00:00+00:00]>
455
- #
474
+ #
456
475
  # # Pass an integer to shift
457
476
  # index.shift(4)
458
477
  # #=>#<DateTimeIndex:83979630 offset=YEAR periods=10 data=[2016-01-01T00:00:00+00:00...2025-01-01T00:00:00+00:00]>
459
478
  def shift distance
460
479
  if distance.is_a?(Fixnum)
461
480
  raise IndexError, "Distance #{distance} cannot be negative" if distance < 0
462
- if @offset
463
- start = @data[0][0]
464
- distance.times { start = @offset + start }
465
- return DateTimeIndex.date_range(
466
- :start => start, :periods => @periods, freq: @offset)
467
- else
468
- raise IndexError, "To shift non-freq date time index pass an offset."
469
- end
481
+ raise IndexError, 'To shift non-freq date time index pass an offset.' unless @offset
482
+
483
+ start = @data[0][0]
484
+ distance.times { start = @offset + start }
485
+ DateTimeIndex.date_range(start: start, periods: @periods, freq: @offset)
470
486
  else # its a Daru::Offset/DateOffset
471
- DateTimeIndex.new(self.to_a.map { |e| distance + e }, freq: :infer)
487
+ DateTimeIndex.new(to_a.map { |e| distance + e }, freq: :infer)
472
488
  end
473
489
  end
474
490
 
475
491
  # Shift all dates in the index to the past. The dates are shifted by the same
476
492
  # amount as that specified in the offset.
477
- #
478
- # @param [Fixnum, Daru::DateOffset, Daru::Offsets::*] distance Fixnum or
479
- # Daru::DateOffset. Distance by which each date should be shifted. Passing
480
- # an offset object to #lag will offset each data point by the offset value.
481
- # Passing a positive integer will offset each data point by the same offset
493
+ #
494
+ # @param [Fixnum, Daru::DateOffset, Daru::Offsets::*] distance Fixnum or
495
+ # Daru::DateOffset. Distance by which each date should be shifted. Passing
496
+ # an offset object to #lag will offset each data point by the offset value.
497
+ # Passing a positive integer will offset each data point by the same offset
482
498
  # that it was created with.
483
499
  # @return [DateTimeIndex] A new lagged DateTimeIndex object.
484
500
  def lag distance
485
501
  if distance.is_a?(Fixnum)
486
502
  raise IndexError, "Distance #{distance} cannot be negative" if distance < 0
487
- if @offset
488
- start = @data[0][0]
489
- distance.times { start = @offset - start }
490
- return DateTimeIndex.date_range(
491
- :start => start, :periods => @periods, freq: @offset)
492
- else
493
- raise IndexError, "To lag non-freq date time index pass an offset."
494
- end
503
+ raise IndexError, 'To lag non-freq date time index pass an offset.' unless @offset
504
+
505
+ start = @data[0][0]
506
+ distance.times { start = @offset - start }
507
+ DateTimeIndex.date_range(start: start, periods: @periods, freq: @offset)
495
508
  else
496
- DateTimeIndex.new(self.to_a.map { |e| distance - e }, freq: :infer)
509
+ DateTimeIndex.new(to_a.map { |e| distance - e }, freq: :infer)
497
510
  end
498
511
  end
499
512
 
500
- def _dump depth
501
- Marshal.dump({data: self.to_a, freq: @offset})
513
+ def _dump(_depth)
514
+ Marshal.dump(data: to_a, freq: @offset)
502
515
  end
503
516
 
504
517
  def self._load data
@@ -521,24 +534,24 @@ module Daru
521
534
  # @return [Array<Fixnum>] Array containing seconds of each index.
522
535
  [:year, :month, :day, :hour, :min, :sec].each do |meth|
523
536
  define_method(meth) do
524
- self.inject([]) do |arr, d|
537
+ each_with_object([]) do |d, arr|
525
538
  arr << d.send(meth)
526
- arr
527
539
  end
528
540
  end
529
541
  end
530
542
 
531
- # Check if a date exists in the index. Will be inferred from string in case
543
+ # Check if a date exists in the index. Will be inferred from string in case
532
544
  # you pass a string. Recommened specifying the full date as a DateTime object.
533
545
  def include? date_time
534
- return false if !(date_time.is_a?(String) or date_time.is_a?(DateTime))
546
+ return false unless date_time.is_a?(String) || date_time.is_a?(DateTime)
535
547
  helper = DateTimeIndexHelper
536
548
  if date_time.is_a?(String)
537
549
  date_precision = helper.determine_date_precision_of date_time
538
550
  date_time = helper.date_time_from date_time, date_precision
539
551
  end
540
552
 
541
- result = @data.bsearch {|d| d[0] >= date_time }
553
+ result = @data.bsearch { |d| d[0] >= date_time }
554
+ return false if result.nil?
542
555
  result[0] == date_time
543
556
  end
544
557
 
@@ -547,4 +560,4 @@ module Daru
547
560
  @data.empty?
548
561
  end
549
562
  end
550
- end
563
+ end