daru 0.1.5 → 0.1.6

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
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