daru 0.1.5 → 0.1.6

Sign up to get free protection for your applications and to get access to all the features.
Files changed (81) hide show
  1. checksums.yaml +4 -4
  2. data/.rubocop.yml +20 -7
  3. data/CONTRIBUTING.md +1 -1
  4. data/History.md +48 -1
  5. data/README.md +3 -3
  6. data/benchmarks/statistics.rb +6 -6
  7. data/benchmarks/where_clause.rb +1 -1
  8. data/benchmarks/where_vs_filter.rb +1 -1
  9. data/daru.gemspec +3 -2
  10. data/lib/daru.rb +14 -6
  11. data/lib/daru/accessors/gsl_wrapper.rb +1 -1
  12. data/lib/daru/accessors/nmatrix_wrapper.rb +2 -0
  13. data/lib/daru/category.rb +1 -1
  14. data/lib/daru/core/group_by.rb +32 -15
  15. data/lib/daru/core/query.rb +4 -4
  16. data/lib/daru/dataframe.rb +196 -48
  17. data/lib/daru/date_time/index.rb +7 -5
  18. data/lib/daru/formatters/table.rb +1 -0
  19. data/lib/daru/index/index.rb +121 -33
  20. data/lib/daru/index/multi_index.rb +83 -3
  21. data/lib/daru/io/csv/converters.rb +18 -0
  22. data/lib/daru/io/io.rb +80 -11
  23. data/lib/daru/io/sql_data_source.rb +10 -0
  24. data/lib/daru/iruby/templates/dataframe.html.erb +3 -50
  25. data/lib/daru/iruby/templates/dataframe_mi.html.erb +3 -56
  26. data/lib/daru/iruby/templates/dataframe_mi_tbody.html.erb +35 -0
  27. data/lib/daru/iruby/templates/dataframe_mi_thead.html.erb +21 -0
  28. data/lib/daru/iruby/templates/dataframe_tbody.html.erb +28 -0
  29. data/lib/daru/iruby/templates/dataframe_thead.html.erb +21 -0
  30. data/lib/daru/iruby/templates/vector.html.erb +3 -25
  31. data/lib/daru/iruby/templates/vector_mi.html.erb +3 -34
  32. data/lib/daru/iruby/templates/vector_mi_tbody.html.erb +26 -0
  33. data/lib/daru/iruby/templates/vector_mi_thead.html.erb +8 -0
  34. data/lib/daru/iruby/templates/vector_tbody.html.erb +17 -0
  35. data/lib/daru/iruby/templates/vector_thead.html.erb +8 -0
  36. data/lib/daru/maths/statistics/dataframe.rb +9 -11
  37. data/lib/daru/maths/statistics/vector.rb +139 -32
  38. data/lib/daru/plotting/gruff/dataframe.rb +13 -15
  39. data/lib/daru/plotting/nyaplot/category.rb +1 -1
  40. data/lib/daru/plotting/nyaplot/dataframe.rb +4 -4
  41. data/lib/daru/plotting/nyaplot/vector.rb +1 -2
  42. data/lib/daru/vector.rb +169 -80
  43. data/lib/daru/version.rb +1 -1
  44. data/spec/category_spec.rb +19 -19
  45. data/spec/core/group_by_spec.rb +47 -0
  46. data/spec/core/query_spec.rb +55 -50
  47. data/spec/daru_spec.rb +22 -0
  48. data/spec/dataframe_spec.rb +118 -6
  49. data/spec/date_time/index_spec.rb +34 -16
  50. data/spec/extensions/rserve_spec.rb +1 -1
  51. data/spec/fixtures/boolean_converter_test.csv +5 -0
  52. data/spec/fixtures/eciresults.html +394 -0
  53. data/spec/fixtures/empty_rows_test.csv +17 -0
  54. data/spec/fixtures/macau.html +3691 -0
  55. data/spec/fixtures/macd_data.csv +150 -0
  56. data/spec/fixtures/moneycontrol.html +6812 -0
  57. data/spec/fixtures/url_test.txt~ +0 -0
  58. data/spec/fixtures/valid_markup.html +62 -0
  59. data/spec/fixtures/wiki_climate.html +1243 -0
  60. data/spec/fixtures/wiki_table_info.html +631 -0
  61. data/spec/formatters/table_formatter_spec.rb +29 -0
  62. data/spec/index/categorical_index_spec.rb +33 -33
  63. data/spec/index/index_spec.rb +134 -41
  64. data/spec/index/multi_index_spec.rb +115 -31
  65. data/spec/io/io_spec.rb +201 -0
  66. data/spec/io/sql_data_source_spec.rb +31 -41
  67. data/spec/iruby/dataframe_spec.rb +17 -19
  68. data/spec/iruby/vector_spec.rb +26 -28
  69. data/spec/maths/statistics/vector_spec.rb +136 -14
  70. data/spec/plotting/gruff/category_spec.rb +3 -3
  71. data/spec/plotting/gruff/dataframe_spec.rb +14 -4
  72. data/spec/plotting/gruff/vector_spec.rb +9 -9
  73. data/spec/plotting/nyaplot/category_spec.rb +5 -9
  74. data/spec/plotting/nyaplot/dataframe_spec.rb +72 -47
  75. data/spec/plotting/nyaplot/vector_spec.rb +5 -11
  76. data/spec/shared/vector_display_spec.rb +12 -14
  77. data/spec/spec_helper.rb +21 -0
  78. data/spec/support/matchers.rb +5 -0
  79. data/spec/vector_spec.rb +222 -72
  80. metadata +68 -23
  81. data/spec/fixtures/stock_data.csv +0 -500
@@ -73,6 +73,8 @@ module Daru
73
73
  query = String.try_convert(query) or
74
74
  raise ArgumentError, "Query must be a string, #{query.class} received"
75
75
 
76
+ db = attempt_sqlite3_connection(db) if db.is_a?(String) && Pathname(db).exist?
77
+
76
78
  case db
77
79
  when DBI::DatabaseHandle
78
80
  DbiAdapter.new(db, query)
@@ -82,6 +84,14 @@ module Daru
82
84
  raise ArgumentError, "Unknown database adapter type #{db.class}"
83
85
  end
84
86
  end
87
+
88
+ def attempt_sqlite3_connection(db)
89
+ DBI.connect("DBI:SQLite3:#{db}")
90
+ rescue SQLite3::NotADatabaseException
91
+ raise ArgumentError, "Expected #{db} to point to a SQLite3 database"
92
+ rescue NameError
93
+ raise NameError, "In order to establish a connection to #{db}, please require 'dbi'"
94
+ end
85
95
  end
86
96
  end
87
97
  end
@@ -1,52 +1,5 @@
1
+ <b> Daru::DataFrame<%= name ? ": #{name} " : ''%>(<%=nrows%>x<%=ncols%>) </b>
1
2
  <table>
2
- <tr>
3
- <th colspan='<%= @vectors.size+1 %>'>Daru::DataFrame<%= name ? ": #{name} " : ''%>(<%=nrows%>x<%=ncols%>)</th>
4
- </tr>
5
-
6
- <% if @vectors.is_a? MultiIndex %>
7
- <% Daru::IRuby::Helpers.tuples_with_colspans(@vectors).each_with_index do |tuple, idx| %>
8
- <tr>
9
- <% if idx.zero? %>
10
- <th rowspan="<%= @vectors.width %>"></th>
11
- <% end %>
12
- <% tuple.each do |idx, span| %>
13
- <th colspan="<%= span %>"><%= idx %></th>
14
- <% end %>
15
- </tr>
16
- <% end %>
17
- <% else %>
18
- <tr>
19
- <th></th>
20
- <% @vectors.each do |vector| %>
21
- <th><%=vector%></th>
22
- <% end %>
23
- </tr>
24
- <% end %>
25
-
26
- <% @index.first(threshold).each_with_index do |index, pos| %>
27
- <tr>
28
- <td><%= index %></td>
29
- <% row.at(pos).each do |element| %>
30
- <td><%= element.to_s %></td>
31
- <% end %>
32
- </tr>
33
- <% end %>
34
-
35
- <% if nrows > threshold %>
36
- <tr>
37
- <% (@vectors.size + 1).times do %>
38
- <td>...</td>
39
- <% end %>
40
- </tr>
41
-
42
- <% last_index = @index.to_a.last
43
- last_row = row_at @index.size-1 %>
44
-
45
- <tr>
46
- <td><%= last_index %></td>
47
- <% last_row.each do |element| %>
48
- <td><%= element.to_s %></td>
49
- <% end %>
50
- </tr>
51
- <% end %>
3
+ <%= table_thead %>
4
+ <%= table_tbody %>
52
5
  </table>
@@ -1,58 +1,5 @@
1
+ <b> Daru::DataFrame<%= name ? ": #{name} " : ''%>(<%=nrows%>x<%=ncols%>) </b>
1
2
  <table>
2
- <tr>
3
- <th colspan='<%= @vectors.size+index.width %>'>Daru::DataFrame<%= name ? ": #{name} " : ''%>(<%=nrows%>x<%=ncols%>)</th>
4
- </tr>
5
- <% if @vectors.is_a? MultiIndex %>
6
- <% Daru::IRuby::Helpers.tuples_with_colspans(@vectors).each_with_index do |tuple, idx| %>
7
- <tr>
8
- <% if idx.zero? %>
9
- <th colspan="<%= index.width %>" rowspan="<%= @vectors.width %>"></th>
10
- <% end %>
11
- <% tuple.each do |idx, span| %>
12
- <th colspan="<%= span %>"><%= idx %></th>
13
- <% end %>
14
- </tr>
15
- <% end %>
16
- <% else %>
17
- <tr>
18
- <th colspan="<%= index.width %>"></th>
19
- <% @vectors.each do |vector| %>
20
- <th><%=vector%></th>
21
- <% end %>
22
- </tr>
23
- <% end %>
24
-
25
- <% Daru::IRuby::Helpers.tuples_with_rowspans(@index).first(threshold).zip(@index.to_a).each do |tuple, index| %>
26
- <tr>
27
- <% tuple.each do |idx, span| %>
28
- <th rowspan="<%= span %>"><%= idx %></th>
29
- <% end %>
30
- <% row[index].each do |element| %>
31
- <td><%= element.to_s %></td>
32
- <% end %>
33
- </tr>
34
- <% end %>
35
-
36
- <% if nrows > threshold %>
37
- <tr>
38
- <% index.width.times do %>
39
- <th>...</th>
40
- <% end %>
41
- <% @vectors.size.times do %>
42
- <td>...</td>
43
- <% end %>
44
- </tr>
45
-
46
- <% last_index = @index.to_a.last
47
- last_row = row[last_index] %>
48
-
49
- <tr>
50
- <% last_index.each do |idx| %>
51
- <th><%= idx %></td>
52
- <% end %>
53
- <% last_row.each do |element| %>
54
- <td><%= element.to_s %></td>
55
- <% end %>
56
- </tr>
57
- <% end %>
3
+ <%= table_thead %>
4
+ <%= table_tbody %>
58
5
  </table>
@@ -0,0 +1,35 @@
1
+ <tbody>
2
+ <% Daru::IRuby::Helpers.tuples_with_rowspans(@index).first(threshold).zip(@index.to_a).each do |tuple, index| %>
3
+ <tr>
4
+ <% tuple.each do |idx, span| %>
5
+ <th rowspan="<%= span %>"><%= idx %></th>
6
+ <% end %>
7
+ <% row[index].each do |element| %>
8
+ <td><%= element.to_s %></td>
9
+ <% end %>
10
+ </tr>
11
+ <% end %>
12
+
13
+ <% if nrows > threshold %>
14
+ <tr>
15
+ <% index.width.times do %>
16
+ <th>...</th>
17
+ <% end %>
18
+ <% @vectors.size.times do %>
19
+ <td>...</td>
20
+ <% end %>
21
+ </tr>
22
+
23
+ <% last_index = @index.to_a.last
24
+ last_row = row[last_index] %>
25
+
26
+ <tr>
27
+ <% last_index.each do |idx| %>
28
+ <th><%= idx %></td>
29
+ <% end %>
30
+ <% last_row.each do |element| %>
31
+ <td><%= element.to_s %></td>
32
+ <% end %>
33
+ </tr>
34
+ <% end %>
35
+ </tbody>
@@ -0,0 +1,21 @@
1
+ <thead>
2
+ <% if @vectors.is_a? MultiIndex %>
3
+ <% Daru::IRuby::Helpers.tuples_with_colspans(@vectors).each_with_index do |tuple, idx| %>
4
+ <tr>
5
+ <% if idx.zero? %>
6
+ <th colspan="<%= index.width %>" rowspan="<%= @vectors.width %>"></th>
7
+ <% end %>
8
+ <% tuple.each do |idx, span| %>
9
+ <th colspan="<%= span %>"><%= idx %></th>
10
+ <% end %>
11
+ </tr>
12
+ <% end %>
13
+ <% else %>
14
+ <tr>
15
+ <th colspan="<%= index.width %>"></th>
16
+ <% @vectors.each do |vector| %>
17
+ <th><%=vector%></th>
18
+ <% end %>
19
+ </tr>
20
+ <% end %>
21
+ </thead>
@@ -0,0 +1,28 @@
1
+ <tbody>
2
+ <% @index.first(threshold).each_with_index do |index, pos| %>
3
+ <tr>
4
+ <td><%= index %></td>
5
+ <% row.at(pos).each do |element| %>
6
+ <td><%= element.to_s %></td>
7
+ <% end %>
8
+ </tr>
9
+ <% end %>
10
+
11
+ <% if nrows > threshold %>
12
+ <tr>
13
+ <% (@vectors.size + 1).times do %>
14
+ <td>...</td>
15
+ <% end %>
16
+ </tr>
17
+
18
+ <% last_index = @index.to_a.last
19
+ last_row = row_at @index.size-1 %>
20
+
21
+ <tr>
22
+ <td><%= last_index %></td>
23
+ <% last_row.each do |element| %>
24
+ <td><%= element.to_s %></td>
25
+ <% end %>
26
+ </tr>
27
+ <% end %>
28
+ </tbody>
@@ -0,0 +1,21 @@
1
+ <thead>
2
+ <% if @vectors.is_a? MultiIndex %>
3
+ <% Daru::IRuby::Helpers.tuples_with_colspans(@vectors).each_with_index do |tuple, idx| %>
4
+ <tr>
5
+ <% if idx.zero? %>
6
+ <th rowspan="<%= @vectors.width %>"></th>
7
+ <% end %>
8
+ <% tuple.each do |idx, span| %>
9
+ <th colspan="<%= span %>"><%= idx %></th>
10
+ <% end %>
11
+ </tr>
12
+ <% end %>
13
+ <% else %>
14
+ <tr>
15
+ <th></th>
16
+ <% @vectors.each do |vector| %>
17
+ <th><%=vector%></th>
18
+ <% end %>
19
+ </tr>
20
+ <% end %>
21
+ </thead>
@@ -1,27 +1,5 @@
1
+ <b> Daru::Vector(<%= size %>)<%= ':category' if category? %> </b>
1
2
  <table>
2
- <tr>
3
- <th colspan="2">Daru::Vector(<%= size %>)<%= ':category' if category? %></th>
4
- </tr>
5
- <% if name %>
6
- <tr>
7
- <th> </th>
8
- <th><%= name %></th>
9
- </tr>
10
- <% end %>
11
-
12
- <% @index.each_with_index.first(threshold).each do |index, pos| %>
13
- <tr>
14
- <td><%= index %></td>
15
- <td><%= self.at(pos) %></td>
16
- </tr>
17
- <% end %>
18
-
19
- <% if size > threshold %>
20
- <% last_index = @index.size-1 %>
21
- <tr><td>...</td><td>...</td></tr>
22
- <tr>
23
- <td><%= last_index %></td>
24
- <td><%= self.at last_index %></td>
25
- </tr>
26
- <% end %>
3
+ <%= table_thead %>
4
+ <%= table_tbody %>
27
5
  </table>
@@ -1,36 +1,5 @@
1
+ <b> Daru::Vector(<%= size %>)<%= ':category' if category? %> </b>
1
2
  <table>
2
- <tr>
3
- <th colspan="<%= index.width+1 %>">Daru::Vector(<%= size %>)<%= ':category' if category? %></th>
4
- </tr>
5
- <% if name %>
6
- <tr>
7
- <th colspan="<%= index.width %>"> </th>
8
- <th><%= name %></th>
9
- </tr>
10
- <% end %>
11
-
12
- <% Daru::IRuby::Helpers.tuples_with_rowspans(@index).first(threshold).zip(to_a).each do |tuple, value| %>
13
- <tr>
14
- <% tuple.each do |idx, span| %>
15
- <th rowspan="<%= span %>"><%= idx %></th>
16
- <% end %>
17
- <td><%= value %></td>
18
- </tr>
19
- <% end %>
20
-
21
- <% if size > threshold %>
22
- <% last_index = @index.to_a.last %>
23
- <tr>
24
- <% last_index.size.times do %>
25
- <th>...</th>
26
- <% end %>
27
- <td>...</td>
28
- </tr>
29
- <tr>
30
- <% last_index.each do |idx| %>
31
- <th><%= idx %></td>
32
- <% end %>
33
- <td><%= self[last_index] %></td>
34
- </tr>
35
- <% end %>
3
+ <%= table_thead %>
4
+ <%= table_tbody %>
36
5
  </table>
@@ -0,0 +1,26 @@
1
+ <tbody>
2
+ <% Daru::IRuby::Helpers.tuples_with_rowspans(@index).first(threshold).zip(to_a).each do |tuple, value| %>
3
+ <tr>
4
+ <% tuple.each do |idx, span| %>
5
+ <th rowspan="<%= span %>"><%= idx %></th>
6
+ <% end %>
7
+ <td><%= value %></td>
8
+ </tr>
9
+ <% end %>
10
+
11
+ <% if size > threshold %>
12
+ <% last_index = @index.to_a.last %>
13
+ <tr>
14
+ <% last_index.size.times do %>
15
+ <th>...</th>
16
+ <% end %>
17
+ <td>...</td>
18
+ </tr>
19
+ <tr>
20
+ <% last_index.each do |idx| %>
21
+ <th><%= idx %></td>
22
+ <% end %>
23
+ <td><%= self[last_index] %></td>
24
+ </tr>
25
+ <% end %>
26
+ </tbody>
@@ -0,0 +1,8 @@
1
+ <thead>
2
+ <% if name %>
3
+ <tr>
4
+ <th colspan="<%= index.width %>"> </th>
5
+ <th><%= name %></th>
6
+ </tr>
7
+ <% end %>
8
+ </thead>
@@ -0,0 +1,17 @@
1
+ <tbody>
2
+ <% @index.each_with_index.first(threshold).each do |index, pos| %>
3
+ <tr>
4
+ <td><%= index %></td>
5
+ <td><%= self.at(pos) %></td>
6
+ </tr>
7
+ <% end %>
8
+
9
+ <% if size > threshold %>
10
+ <% last_index = @index.size-1 %>
11
+ <tr><td>...</td><td>...</td></tr>
12
+ <tr>
13
+ <td><%= last_index %></td>
14
+ <td><%= self.at last_index %></td>
15
+ </tr>
16
+ <% end %>
17
+ </tbody>
@@ -0,0 +1,8 @@
1
+ <thead>
2
+ <% if name %>
3
+ <tr>
4
+ <th> </th>
5
+ <th><%= name %></th>
6
+ </tr>
7
+ <% end %>
8
+ </thead>
@@ -22,7 +22,7 @@ module Daru
22
22
  # Calculate the minimum value of each numeric vector
23
23
  # @!method product
24
24
  # Compute the product of each numeric vector
25
- [:mean, :variance_sample, :range, :median, :mode, :std, :sum, :count, :min, :product].each do |meth|
25
+ %i[mean variance_sample range median mode std sum count min product].each do |meth|
26
26
  define_method(meth) do
27
27
  compute_stats meth
28
28
  end
@@ -70,9 +70,9 @@ module Daru
70
70
  # @!method rolling_variance
71
71
  # Calculate moving variance
72
72
  # @param [Integer] n (10) Loopback length. Default to 10.
73
- [
74
- :cumsum,:standardize,:acf,:ema,:rolling_mean,:rolling_median,:rolling_max,
75
- :rolling_min,:rolling_count,:rolling_std,:rolling_variance, :rolling_sum
73
+ %i[
74
+ cumsum standardize acf ema rolling_mean rolling_median rolling_max
75
+ rolling_min rolling_count rolling_std rolling_variance rolling_sum
76
76
  ].each do |meth|
77
77
  define_method(meth) do |*args|
78
78
  apply_method_to_numerics meth, *args
@@ -88,7 +88,7 @@ module Daru
88
88
  # be applied to numeric vectors. Default is [:count, :mean, :std, :max,
89
89
  # :min]. Methods will be applied in the specified order.
90
90
  def describe methods=nil
91
- methods ||= [:count, :mean, :std, :min, :max]
91
+ methods ||= %i[count mean std min max]
92
92
 
93
93
  description_hash = {}
94
94
  numeric_vectors.each do |vec|
@@ -133,17 +133,15 @@ module Daru
133
133
  # Calculate sample variance-covariance between the numeric vectors.
134
134
  def covariance
135
135
  cache = Hash.new do |h, (col, row)|
136
- h[[col, row]] = vector_cov(self[row],self[col])
136
+ value = vector_cov(self[row],self[col])
137
+ h[[col, row]] = value
138
+ h[[row, col]] = value
137
139
  end
138
140
  vectors = numeric_vectors
139
141
 
140
142
  mat_rows = vectors.collect do |row|
141
143
  vectors.collect do |col|
142
- if row == col
143
- self[row].variance
144
- else
145
- cache[[col,row]]
146
- end
144
+ row == col ? self[row].variance : cache[[col,row]]
147
145
  end
148
146
  end
149
147
 
@@ -19,10 +19,6 @@ module Daru
19
19
  @data.product
20
20
  end
21
21
 
22
- def min
23
- @data.min
24
- end
25
-
26
22
  def range
27
23
  max - min
28
24
  end
@@ -45,7 +41,7 @@ module Daru
45
41
  # be applied to vectors. Default is [:count, :mean, :std, :max,
46
42
  # :min]. Methods will be applied in the specified order.
47
43
  def describe methods=nil
48
- methods ||= [:count, :mean, :std, :min, :max]
44
+ methods ||= %i[count mean std min max]
49
45
  description = methods.map { |m| send(m) }
50
46
  Daru::Vector.new(description, index: methods, name: :statistics)
51
47
  end
@@ -70,24 +66,129 @@ module Daru
70
66
  reject_values(*Daru::MISSING_VALUES).uniq.reset_index!
71
67
  end
72
68
 
73
- # Maximum element of the vector.
69
+ # Returns the maximum value present in the vector.
74
70
  #
75
- # @param return_type [Symbol] Data type of the returned value. Defaults
76
- # to returning only the maximum number but passing *:vector* will return
77
- # a Daru::Vector with the index of the corresponding maximum value.
78
- def max return_type=:stored_type
79
- max_value = @data.max
80
- if return_type == :vector
81
- Daru::Vector.new({index_of(max_value) => max_value}, name: @name, dtype: @dtype)
82
- else
83
- max_value
84
- end
71
+ # @example
72
+ #
73
+ # dv = Daru::Vector.new (["Tyrion", "Daenerys", "Jon Starkgaryen"]), index: Daru::Index.new([:t, :d, :j])
74
+ # #=>
75
+ # # #<Daru::Vector(3)>
76
+ # # t Tyrion
77
+ # # d Daenerys
78
+ # # j Jon Starkgaryen
79
+ #
80
+ # dv.max
81
+ # #=> "Tyrion"
82
+ #
83
+ # dv.max(2) { |a,b| a.size <=> b.size }
84
+ # #=> ["Jon Starkgaryen","Daenerys"]
85
+ #
86
+ # dv.max(2) { |i| i.size }
87
+ # #=> ["Jon Starkgaryen","Daenerys"]
88
+ def max(size=nil, &block)
89
+ data = @data.data.to_a
90
+ data = if block_given?
91
+ if block.parameters.count == 1 # Object block like { |x| x.size }
92
+ data.sort_by(&block)
93
+ else # Comparative block like { |a,b| a.size <=> b.size }
94
+ data.sort(&block)
95
+ end
96
+ else
97
+ data.sort
98
+ end
99
+ size.nil? ? data.last : data[data.count-size..-1].reverse
100
+ end
101
+
102
+ # Returns the index of the maximum value present in the vector.
103
+ #
104
+ # @example
105
+ #
106
+ # dv = Daru::Vector.new (["Tyrion", "Daenerys", "Jon Starkgaryen"]), index: Daru::Index.new([:t, :d, :j])
107
+ # #=>
108
+ # # #<Daru::Vector(3)>
109
+ # # t Tyrion
110
+ # # d Daenerys
111
+ # # j Jon Starkgaryen
112
+ #
113
+ # dv.index_of_max
114
+ # #=> :t
115
+ #
116
+ # dv.index_of_max(2) { |a,b| a.size <=> b.size }
117
+ # #=> [:j, :d]
118
+ #
119
+ # dv.max(2) { |i| i.size }
120
+ # #=> [:j, :d]
121
+ def index_of_max(size=nil,&block)
122
+ data = @data.data.to_a
123
+ indx = @index.to_a
124
+ vals = max(size,&block)
125
+ vals.is_a?(Array) ? (vals.map { |x| indx[data.index(x)] }) : indx[data.index(vals)]
126
+ end
127
+
128
+ # Returns the minimum value present in the vector.
129
+ #
130
+ # @example
131
+ #
132
+ # dv = Daru::Vector.new (["Tyrion", "Daenerys", "Jon Starkgaryen"]), index: Daru::Index.new([:t, :d, :j])
133
+ # #=>
134
+ # # #<Daru::Vector(3)>
135
+ # # t Tyrion
136
+ # # d Daenerys
137
+ # # j Jon Starkgaryen
138
+ #
139
+ # dv.min
140
+ # #=> "Daenerys"
141
+ #
142
+ # dv.min(2) { |a,b| a.size <=> b.size }
143
+ # #=> ["Tyrion","Daenerys"]
144
+ #
145
+ # dv.min(2) { |i| i.size }
146
+ # #=> ["Tyrion","Daenerys"]
147
+ def min(size=nil, &block)
148
+ data = @data.data.to_a
149
+ data = if block_given?
150
+ if block.parameters.count == 1 # Object block like { |x| x.size }
151
+ data.sort_by(&block)
152
+ else # Comparative block like { |a,b| a.size <=> b.size }
153
+ data.sort(&block)
154
+ end
155
+ else
156
+ data.sort
157
+ end
158
+ size.nil? ? data.first : data[0..size-1]
159
+ end
160
+
161
+ # Returns the index of the minimum value present in the vector.
162
+ #
163
+ # @example
164
+ #
165
+ # dv = Daru::Vector.new (["Tyrion", "Daenerys", "Jon Starkgaryen"]), index: Daru::Index.new([:t, :d, :j])
166
+ # #=>
167
+ # # #<Daru::Vector(3)>
168
+ # # t Tyrion
169
+ # # d Daenerys
170
+ # # j Jon Starkgaryen
171
+ #
172
+ # dv.index_of_min
173
+ # #=> :d
174
+ #
175
+ # dv.index_of_min(2) { |a,b| a.size <=> b.size }
176
+ # #=> [:t, :d]
177
+ #
178
+ # dv.index_of_min(2) { |i| i.size }
179
+ # #=> [:t, :d]
180
+ def index_of_min(size=nil,&block)
181
+ data = @data.data.to_a
182
+ indx = @index.to_a
183
+ vals = min(size,&block)
184
+ vals.is_a?(Array) ? (vals.map { |x| indx[data.index(x)] }) : indx[data.index(vals)]
85
185
  end
86
186
 
87
- # Return a Vector with the max element and its index.
187
+ # Return the maximum element present in the Vector, as a Vector.
88
188
  # @return [Daru::Vector]
89
189
  def max_index
90
- max :vector
190
+ max_value = @data.max
191
+ Daru::Vector.new({index_of(max_value) => max_value}, name: @name, dtype: @dtype)
91
192
  end
92
193
 
93
194
  def frequencies
@@ -470,7 +571,7 @@ module Daru
470
571
  # @!method rolling_variance
471
572
  # Calculate rolling variance
472
573
  # @param [Integer] n (10) Loopback length
473
- [:count, :mean, :median, :max, :min, :sum, :std, :variance].each do |meth|
574
+ %i[count mean median max min sum std variance].each do |meth|
474
575
  define_method("rolling_#{meth}".to_sym) do |n=10|
475
576
  rolling(meth, n)
476
577
  end
@@ -581,26 +682,28 @@ module Daru
581
682
 
582
683
  # Moving Average Convergence-Divergence.
583
684
  # Calculates the MACD (moving average convergence-divergence) of the time
584
- # series - this is a comparison of a fast EMA with a slow EMA.
585
- #
586
- # == Arguments
587
- # * *fast*: integer, (default = 12) - fast component of MACD
588
- # * *slow*: integer, (default = 26) - slow component of MACD
589
- # * *signal*: integer, (default = 9) - signal component of MACD
685
+ # series.
686
+ # @see https://en.wikipedia.org/wiki/MACD
590
687
  #
591
- # == Usage
688
+ # @param fast [Integer] fast period of MACD (default 12)
689
+ # @param slow [Integer] slow period of MACD (default 26)
690
+ # @param signal [Integer] signal period of MACD (default 9)
592
691
  #
692
+ # @example Create a series and calculate MACD values
593
693
  # ts = Daru::Vector.new((1..100).map { rand })
594
694
  # # => [0.69, 0.23, 0.44, 0.71, ...]
595
- # ts.macd(13)
695
+ # macdseries, macdsignal, macdhist = ts.macd
696
+ # macdseries, macdsignal, macdhist = ts.macd(13)
697
+ # macdseries, macdsignal, macdhist = ts.macd(signal=5)
596
698
  #
597
- # == Returns
699
+ # @return [Array<Daru::Vector>] macdseries, macdsignal and macdhist are
700
+ # returned as an array of three Daru::Vectors
598
701
  #
599
- # Array of two Daru::Vectors - comparison of fast EMA with slow and EMA with
600
- # signal value
601
702
  def macd(fast=12, slow=26, signal=9)
602
- series = ema(fast) - ema(slow)
603
- [series, series.ema(signal)]
703
+ macdseries = ema(fast) - ema(slow)
704
+ macdsignal = macdseries.ema(signal)
705
+ macdhist = macdseries - macdsignal
706
+ [macdseries, macdsignal, macdhist]
604
707
  end
605
708
 
606
709
  # Calculates the autocorrelation coefficients of the series.
@@ -688,6 +791,10 @@ module Daru
688
791
  alias :ss :sum_of_squares
689
792
  alias :percentil :percentile
690
793
  alias :se :standard_error
794
+ alias :max_by :max
795
+ alias :min_by :min
796
+ alias :index_of_max_by :index_of_max
797
+ alias :index_of_min_by :index_of_min
691
798
 
692
799
  private
693
800