daru 0.1.3.1 → 0.1.4

Sign up to get free protection for your applications and to get access to all the features.
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