daru 0.1.3.1 → 0.1.4

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 (92) hide show
  1. checksums.yaml +4 -4
  2. data/.gitignore +2 -0
  3. data/.rspec +2 -1
  4. data/.rspec_formatter.rb +33 -0
  5. data/.rubocop.yml +26 -2
  6. data/History.md +38 -0
  7. data/README.md +22 -13
  8. data/Rakefile +50 -2
  9. data/benchmarks/csv_reading.rb +22 -0
  10. data/daru.gemspec +9 -2
  11. data/lib/daru.rb +36 -4
  12. data/lib/daru/accessors/array_wrapper.rb +6 -1
  13. data/lib/daru/accessors/dataframe_by_row.rb +10 -2
  14. data/lib/daru/accessors/gsl_wrapper.rb +1 -3
  15. data/lib/daru/accessors/nmatrix_wrapper.rb +9 -0
  16. data/lib/daru/category.rb +935 -0
  17. data/lib/daru/core/group_by.rb +29 -38
  18. data/lib/daru/core/merge.rb +186 -145
  19. data/lib/daru/core/query.rb +22 -11
  20. data/lib/daru/dataframe.rb +976 -885
  21. data/lib/daru/date_time/index.rb +166 -166
  22. data/lib/daru/date_time/offsets.rb +66 -77
  23. data/lib/daru/formatters/table.rb +54 -0
  24. data/lib/daru/helpers/array.rb +40 -0
  25. data/lib/daru/index.rb +476 -73
  26. data/lib/daru/io/io.rb +66 -45
  27. data/lib/daru/io/sql_data_source.rb +33 -62
  28. data/lib/daru/iruby/helpers.rb +38 -0
  29. data/lib/daru/iruby/templates/dataframe.html.erb +52 -0
  30. data/lib/daru/iruby/templates/dataframe_mi.html.erb +58 -0
  31. data/lib/daru/iruby/templates/multi_index.html.erb +12 -0
  32. data/lib/daru/iruby/templates/vector.html.erb +27 -0
  33. data/lib/daru/iruby/templates/vector_mi.html.erb +36 -0
  34. data/lib/daru/maths/arithmetic/dataframe.rb +16 -18
  35. data/lib/daru/maths/arithmetic/vector.rb +4 -6
  36. data/lib/daru/maths/statistics/dataframe.rb +8 -15
  37. data/lib/daru/maths/statistics/vector.rb +120 -98
  38. data/lib/daru/monkeys.rb +12 -40
  39. data/lib/daru/plotting/gruff.rb +3 -0
  40. data/lib/daru/plotting/gruff/category.rb +49 -0
  41. data/lib/daru/plotting/gruff/dataframe.rb +91 -0
  42. data/lib/daru/plotting/gruff/vector.rb +57 -0
  43. data/lib/daru/plotting/nyaplot.rb +3 -0
  44. data/lib/daru/plotting/nyaplot/category.rb +34 -0
  45. data/lib/daru/plotting/nyaplot/dataframe.rb +187 -0
  46. data/lib/daru/plotting/nyaplot/vector.rb +46 -0
  47. data/lib/daru/vector.rb +694 -421
  48. data/lib/daru/version.rb +1 -1
  49. data/profile/_base.rb +23 -0
  50. data/profile/df_to_a.rb +10 -0
  51. data/profile/filter.rb +13 -0
  52. data/profile/joining.rb +13 -0
  53. data/profile/sorting.rb +12 -0
  54. data/profile/vector_each_with_index.rb +9 -0
  55. data/spec/accessors/wrappers_spec.rb +2 -4
  56. data/spec/categorical_spec.rb +1734 -0
  57. data/spec/core/group_by_spec.rb +52 -2
  58. data/spec/core/merge_spec.rb +63 -2
  59. data/spec/core/query_spec.rb +236 -80
  60. data/spec/dataframe_spec.rb +1373 -79
  61. data/spec/date_time/data_spec.rb +3 -5
  62. data/spec/date_time/index_spec.rb +154 -17
  63. data/spec/date_time/offsets_spec.rb +3 -4
  64. data/spec/fixtures/empties.dat +2 -0
  65. data/spec/fixtures/strings.dat +2 -0
  66. data/spec/formatters/table_formatter_spec.rb +99 -0
  67. data/spec/helpers_spec.rb +8 -0
  68. data/spec/index/categorical_index_spec.rb +168 -0
  69. data/spec/index/index_spec.rb +283 -0
  70. data/spec/index/multi_index_spec.rb +570 -0
  71. data/spec/io/io_spec.rb +31 -4
  72. data/spec/io/sql_data_source_spec.rb +0 -1
  73. data/spec/iruby/dataframe_spec.rb +172 -0
  74. data/spec/iruby/helpers_spec.rb +49 -0
  75. data/spec/iruby/multi_index_spec.rb +37 -0
  76. data/spec/iruby/vector_spec.rb +107 -0
  77. data/spec/math/arithmetic/dataframe_spec.rb +71 -13
  78. data/spec/math/arithmetic/vector_spec.rb +8 -10
  79. data/spec/math/statistics/dataframe_spec.rb +3 -5
  80. data/spec/math/statistics/vector_spec.rb +45 -55
  81. data/spec/monkeys_spec.rb +32 -9
  82. data/spec/plotting/dataframe_spec.rb +386 -0
  83. data/spec/plotting/vector_spec.rb +230 -0
  84. data/spec/shared/vector_display_spec.rb +215 -0
  85. data/spec/spec_helper.rb +23 -0
  86. data/spec/vector_spec.rb +905 -138
  87. metadata +143 -11
  88. data/.rubocop_todo.yml +0 -44
  89. data/lib/daru/plotting/dataframe.rb +0 -104
  90. data/lib/daru/plotting/vector.rb +0 -38
  91. data/spec/daru_spec.rb +0 -58
  92. data/spec/index_spec.rb +0 -375
@@ -1,58 +0,0 @@
1
- require 'spec_helper.rb'
2
-
3
- describe "Daru.lazy_update" do
4
- context "A variable which will set whether Vector metadata is updated immediately or lazily." do
5
- describe Daru::Vector do
6
- it "does updates metadata immediately when LAZY_UPDATE is set to default false" do
7
- v = Daru::Vector.new [1,2,3,4,nil,nil,3,nil]
8
- v[1] = nil
9
-
10
- expect(v.missing_positions.include?(1)).to eq(true)
11
- end
12
-
13
- it "does NOT update metadata immediately when @@lazy_update is set to default true. Update done when #update is called" do
14
- Daru.lazy_update = true
15
- v = Daru::Vector.new [1,2,3,4,nil,nil]
16
- v[1] = nil
17
- v[0] = nil
18
-
19
- expect(v.missing_positions.include?(0)).to eq(false)
20
- expect(v.missing_positions.include?(1)).to eq(false)
21
-
22
- v.update
23
- expect(v.missing_positions.include?(0)).to eq(true)
24
- expect(v.missing_positions.include?(1)).to eq(true)
25
-
26
- Daru.lazy_update = false
27
- end
28
- end
29
-
30
- describe Daru::DataFrame do
31
- before do
32
- v = Daru::Vector.new [1,2,3,4,nil,nil,3,nil]
33
- @df = Daru::DataFrame.new({a: v, b: v, c: v})
34
- end
35
-
36
- it "does updates metadata immediately when LAZY_UPDATE is set to default false" do
37
- @df[:a][1] = nil
38
-
39
- expect(@df[:a].missing_positions.include?(1)).to eq(true)
40
- end
41
-
42
- it "does NOT update metadata immediately when @@lazy_update is set to default true. Update done when #update is called" do
43
- Daru.lazy_update = true
44
- @df[:c][0] = nil
45
- @df[:a][1] = nil
46
-
47
- expect(@df[:c].missing_positions.include?(0)).to eq(false)
48
- expect(@df[:a].missing_positions.include?(1)).to eq(false)
49
-
50
- @df.update
51
- expect(@df[:c].missing_positions.include?(0)).to eq(true)
52
- expect(@df[:a].missing_positions.include?(1)).to eq(true)
53
-
54
- Daru.lazy_update = false
55
- end
56
- end
57
- end
58
- end
@@ -1,375 +0,0 @@
1
- require 'spec_helper.rb'
2
-
3
- describe Daru::Index do
4
- context ".new" do
5
- it "creates an Index object if Index-like data is supplied" do
6
- i = Daru::Index.new [:one, 'one', 1, 2, :two]
7
- expect(i.class).to eq(Daru::Index)
8
- expect(i.to_a) .to eq([:one, 'one', 1, 2, :two])
9
- end
10
-
11
- it "creates a MultiIndex if tuples are supplied" do
12
- i = Daru::Index.new([
13
- [:b,:one,:bar],
14
- [:b,:two,:bar],
15
- [:b,:two,:baz],
16
- [:b,:one,:foo]
17
- ])
18
-
19
- expect(i.class).to eq(Daru::MultiIndex)
20
- expect(i.levels).to eq([[:b], [:one, :two], [:bar, :baz, :foo]])
21
- expect(i.labels).to eq([[0,0,0,0],[0,1,1,0],[0,0,1,2]])
22
- end
23
-
24
- it "creates DateTimeIndex if date-like objects specified" do
25
- i = Daru::Index.new([
26
- DateTime.new(2012,2,4), DateTime.new(2012,2,5), DateTime.new(2012,2,6)])
27
- expect(i.class).to eq(Daru::DateTimeIndex)
28
- expect(i.to_a).to eq([DateTime.new(2012,2,4), DateTime.new(2012,2,5), DateTime.new(2012,2,6)])
29
- expect(i.frequency).to eq('D')
30
- end
31
- end
32
-
33
- context "#initialize" do
34
- it "creates an Index from Array" do
35
- idx = Daru::Index.new ['speaker', 'mic', 'guitar', 'amp']
36
-
37
- expect(idx.to_a).to eq(['speaker', 'mic', 'guitar', 'amp'])
38
- end
39
-
40
- it "creates an Index from Range" do
41
- idx = Daru::Index.new 1..5
42
-
43
- expect(idx).to eq(Daru::Index.new [1, 2, 3, 4, 5])
44
- end
45
-
46
- it "raises ArgumentError on invalid input type" do
47
- expect { Daru::Index.new 'foo' }.to raise_error ArgumentError
48
- end
49
-
50
- it "accepts all sorts of objects for Indexing" do
51
- idx = Daru::Index.new [:a, 'a', :hello, '23', 23]
52
-
53
- expect(idx.to_a).to eq([:a, 'a', :hello, '23', 23])
54
- end
55
- end
56
-
57
- context "#size" do
58
- it "correctly returns the size of the index" do
59
- idx = Daru::Index.new ['speaker', 'mic', 'guitar', 'amp']
60
-
61
- expect(idx.size).to eq(4)
62
- end
63
- end
64
-
65
- context "#&" do
66
- it "returns an intersection of 2 index objects" do
67
- end
68
- end
69
-
70
- context "#|" do
71
- before :each do
72
- @left = Daru::Index.new [:miles, :geddy, :eric]
73
- @right = Daru::Index.new [:bob, :jimi, :richie]
74
- end
75
-
76
- it "unions 2 indexes and returns an Index" do
77
- expect(@left | @right).to eq([:miles, :geddy, :eric, :bob, :jimi, :richie].to_index)
78
- end
79
-
80
- it "unions an Index and an Array to return an Index" do
81
- expect(@left | [:bob, :jimi, :richie]).to eq([:miles, :geddy, :eric,
82
- :bob, :jimi, :richie].to_index)
83
- end
84
- end
85
-
86
- context "#[]" do
87
- before do
88
- @id = Daru::Index.new [:one, :two, :three, :four, :five, :six, :seven]
89
- @mixed_id = Daru::Index.new ['a','b','c',:d,:a,8,3,5]
90
- end
91
-
92
- it "works with ranges" do
93
- expect(@id[:two..:five]).to eq(Daru::Index.new([:two, :three, :four, :five]))
94
-
95
- expect(@mixed_id['a'..'c']).to eq(Daru::Index.new(['a','b','c']))
96
-
97
- # If both start and end are numbers then refer to numerical indexes
98
- expect(@mixed_id[0..2]).to eq(Daru::Index.new(['a','b','c']))
99
-
100
- # If atleast one is a number then refer to actual indexing
101
- expect(@mixed_id.slice('b',8)).to eq(Daru::Index.new(['b','c',:d,:a,8]))
102
- end
103
-
104
- it "returns multiple keys if specified multiple indices" do
105
- expect(@id[0,1,3,4]).to eq(Daru::Index.new([:one, :two, :four, :five]))
106
- expect(@mixed_id[0,5,3,2]).to eq(Daru::Index.new(['a', 8, :d, 'c']))
107
- end
108
-
109
- it "returns correct index position for non-numeric index" do
110
- expect(@id[:four]).to eq(3)
111
- expect(@id[3]).to eq(3)
112
- end
113
-
114
- it "returns correct index position for mixed index" do
115
- expect(@mixed_id[8]).to eq(5)
116
- expect(@mixed_id['c']).to eq(2)
117
- end
118
- end
119
- end
120
-
121
- describe Daru::MultiIndex do
122
- before(:each) do
123
- @index_tuples = [
124
- [:a,:one,:bar],
125
- [:a,:one,:baz],
126
- [:a,:two,:bar],
127
- [:a,:two,:baz],
128
- [:b,:one,:bar],
129
- [:b,:two,:bar],
130
- [:b,:two,:baz],
131
- [:b,:one,:foo],
132
- [:c,:one,:bar],
133
- [:c,:one,:baz],
134
- [:c,:two,:foo],
135
- [:c,:two,:bar]
136
- ]
137
- @multi_mi = Daru::MultiIndex.from_tuples(@index_tuples)
138
- end
139
-
140
- context ".initialize" do
141
- it "accepts labels and levels as arguments" do
142
- mi = Daru::MultiIndex.new(
143
- levels: [[:a,:b,:c], [:one, :two]],
144
- labels: [[0,0,1,1,2,2], [0,1,0,1,0,1]])
145
-
146
- expect(mi[:a, :two]).to eq(1)
147
- end
148
-
149
- it "raises error for wrong number of labels or levels" do
150
- expect {
151
- Daru::MultiIndex.new(
152
- levels: [[:a,:a,:b,:b,:c,:c], [:one, :two]],
153
- labels: [[0,0,1,1,2,2]])
154
- }.to raise_error
155
- end
156
- end
157
-
158
- context ".from_tuples" do
159
- it "creates 2 layer MultiIndex from tuples" do
160
- tuples = [
161
- [:a, :one],
162
- [:a, :two],
163
- [:b, :one],
164
- [:b, :two],
165
- [:c, :one],
166
- [:c, :two]
167
- ]
168
- mi = Daru::MultiIndex.from_tuples(tuples)
169
- expect(mi.levels).to eq([[:a, :b, :c], [:one,:two]])
170
- expect(mi.labels).to eq([[0,0,1,1,2,2], [0,1,0,1,0,1]])
171
- end
172
-
173
- it "creates a triple layer MultiIndex from tuples" do
174
- expect(@multi_mi.levels).to eq([[:a,:b,:c], [:one, :two],[:bar,:baz,:foo]])
175
- expect(@multi_mi.labels).to eq([
176
- [0,0,0,0,1,1,1,1,2,2,2,2],
177
- [0,0,1,1,0,1,1,0,0,0,1,1],
178
- [0,1,0,1,0,0,1,2,0,1,2,0]
179
- ])
180
- end
181
- end
182
-
183
- context "#size" do
184
- it "returns size of MultiIndex" do
185
- expect(@multi_mi.size).to eq(12)
186
- end
187
- end
188
-
189
- context "#[]" do
190
- it "returns the row number when specifying the complete tuple" do
191
- expect(@multi_mi[:a, :one, :baz]).to eq(1)
192
- end
193
-
194
- it "returns MultiIndex when specifying incomplete tuple" do
195
- expect(@multi_mi[:b]).to eq(Daru::MultiIndex.from_tuples([
196
- [:b,:one,:bar],
197
- [:b,:two,:bar],
198
- [:b,:two,:baz],
199
- [:b,:one,:foo]
200
- ]))
201
- expect(@multi_mi[:b, :one]).to eq(Daru::MultiIndex.from_tuples([
202
- [:b,:one,:bar],
203
- [:b,:one,:foo]
204
- ]))
205
- # TODO: Return Daru::Index if a single layer of indexes is present.
206
- end
207
-
208
- it "returns MultiIndex when specifying wholly numeric ranges" do
209
- expect(@multi_mi[3..6]).to eq(Daru::MultiIndex.from_tuples([
210
- [:a,:two,:baz],
211
- [:b,:one,:bar],
212
- [:b,:two,:bar],
213
- [:b,:two,:baz]
214
- ]))
215
- end
216
-
217
- it "raises error when specifying invalid index" do
218
- expect { @multi_mi[:a, :three] }.to raise_error IndexError
219
- expect { @multi_mi[:a, :one, :xyz] }.to raise_error IndexError
220
- expect { @multi_mi[:x] }.to raise_error IndexError
221
- expect { @multi_mi[:x, :one] }.to raise_error IndexError
222
- expect { @multi_mi[:x, :one, :bar] }.to raise_error IndexError
223
- end
224
-
225
- it "works with numerical first levels" do
226
- mi = Daru::MultiIndex.from_tuples([
227
- [2000, 'M'],
228
- [2000, 'F'],
229
- [2001, 'M'],
230
- [2001, 'F']
231
- ])
232
-
233
- expect(mi[2000]).to eq(Daru::MultiIndex.from_tuples([
234
- [2000, 'M'],
235
- [2000, 'F']
236
- ]))
237
-
238
- expect(mi[2000,'M']).to eq(0)
239
- end
240
- end
241
-
242
- context "#include?" do
243
- it "checks if a completely specified tuple exists" do
244
- expect(@multi_mi.include?([:a,:one,:bar])).to eq(true)
245
- end
246
-
247
- it "checks if a top layer incomplete tuple exists" do
248
- expect(@multi_mi.include?([:a])).to eq(true)
249
- end
250
-
251
- it "checks if a middle layer incomplete tuple exists" do
252
- expect(@multi_mi.include?([:a, :one])).to eq(true)
253
- end
254
-
255
- it "checks for non-existence of a tuple" do
256
- expect(@multi_mi.include?([:boo])).to eq(false)
257
- end
258
- end
259
-
260
- context "#key" do
261
- it "returns the tuple of the specified number" do
262
- expect(@multi_mi.key(3)).to eq([:a,:two,:baz])
263
- end
264
-
265
- it "returns nil for non-existent pointer number" do
266
- expect {
267
- @multi_mi.key(100)
268
- }.to raise_error ArgumentError
269
- end
270
- end
271
-
272
- context "#to_a" do
273
- it "returns tuples as an Array" do
274
- expect(@multi_mi.to_a).to eq(@index_tuples)
275
- end
276
- end
277
-
278
- context "#dup" do
279
- it "completely duplicates the object" do
280
- duplicate = @multi_mi.dup
281
- expect(duplicate) .to eq(@multi_mi)
282
- expect(duplicate.object_id).to_not eq(@multi_mi.object_id)
283
- end
284
- end
285
-
286
- context "#==" do
287
- it "returns false for unequal MultiIndex comparisons" do
288
- mi1 = Daru::MultiIndex.from_tuples([
289
- [:a, :one, :bar],
290
- [:a, :two, :baz],
291
- [:b, :one, :foo],
292
- [:b, :two, :bar]
293
- ])
294
- mi2 = Daru::MultiIndex.from_tuples([
295
- [:a, :two, :bar],
296
- [:b, :one, :foo],
297
- [:a, :one, :baz],
298
- [:b, :two, :baz]
299
- ])
300
-
301
- expect(mi1 == mi2).to eq(false)
302
- end
303
- end
304
-
305
- context "#values" do
306
- it "returns an array of indices in order" do
307
- mi = Daru::MultiIndex.from_tuples([
308
- [:a, :one, :bar],
309
- [:a, :two, :baz],
310
- [:b, :one, :foo],
311
- [:b, :two, :bar]
312
- ])
313
-
314
- expect(mi.values).to eq([0,1,2,3])
315
- end
316
- end
317
-
318
- context "#|" do
319
- before do
320
- @mi1 = Daru::MultiIndex.from_tuples([
321
- [:a, :one, :bar],
322
- [:a, :two, :baz],
323
- [:b, :one, :foo],
324
- [:b, :two, :bar]
325
- ])
326
- @mi2 = Daru::MultiIndex.from_tuples([
327
- [:a, :two, :bar],
328
- [:b, :one, :foo],
329
- [:a, :one, :baz],
330
- [:b, :two, :baz]
331
- ])
332
- end
333
-
334
- it "returns a union of two MultiIndex objects" do
335
- expect(@mi1 | @mi2).to eq(Daru::MultiIndex.new(
336
- levels: [[:a, :b], [:one, :two], [:bar, :baz, :foo]],
337
- labels: [
338
- [0, 0, 1, 1, 0, 0, 1],
339
- [0, 1, 0, 1, 1, 0, 1],
340
- [0, 1, 2, 0, 0, 1, 1]
341
- ])
342
- )
343
- end
344
- end
345
-
346
- context "#&" do
347
- it "returns the intersection of two MI objects" do
348
- end
349
- end
350
-
351
- context "#empty?" do
352
- it "returns true if nothing present in MultiIndex" do
353
- expect(Daru::MultiIndex.new(labels: [[]], levels: [[]]).empty?).to eq(true)
354
- end
355
- end
356
-
357
- context "#drop_left_level" do
358
- it "drops the leftmost level" do
359
- expect(
360
- Daru::MultiIndex.from_tuples([
361
- [:c,:one,:bar],
362
- [:c,:one,:baz],
363
- [:c,:two,:foo],
364
- [:c,:two,:bar]
365
- ]).drop_left_level).to eq(
366
- Daru::MultiIndex.from_tuples([
367
- [:one,:bar],
368
- [:one,:baz],
369
- [:two,:foo],
370
- [:two,:bar]
371
- ])
372
- )
373
- end
374
- end
375
- end