daru_lite 0.2.0 → 0.2.1

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.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: bebf18b1b341f84a4728386060168694ffb47fdd49af1c4621db8a4a3591aa44
4
- data.tar.gz: 1f1bbf2e6ef445496d1f7c58a79e8b74054a78b6cfdcf1f8e4431870cddce437
3
+ metadata.gz: 6da8c79960f009b08e12c9d252a267e4d69d6c2152ded63fbe8180891eb25b86
4
+ data.tar.gz: 074d65df9bbc034b37089cf0938a5df45006f8e264ed259721d5823e0ae41c3b
5
5
  SHA512:
6
- metadata.gz: e1a020700e73fb9a48bfefb225ab79d465658df60fd95bed92ad4053533a0f6f4d6ea1d4e7b5e4dd10a11b79d7f2a5ade80345a87a81efb2eea5124db29d77be
7
- data.tar.gz: 148611db5a2ef6c16b2974131f1c7a1e8298f7537d9868d26a248181478266bae61ce2e1810f6d513391fbfa7deaf66c239491102eae56d698791da26665827a
6
+ metadata.gz: 56055dcbc442963a8c9881d0b86c767cf9d49d382b1f78b33e7603d83a496028116fef819b38fd15110f67bacccf143354efdba9a919fe829d54006c2e0e6bd5
7
+ data.tar.gz: b3b20cfa80cd6ff336979d1ec836673de99f828883d45186a2762b396ab85ed7b57c8b75709b9ff12623121ed34c707ad66b3ad26aa530e98f43aa5fb27dd4a0
@@ -1,15 +1,6 @@
1
1
  name: CI
2
2
  on: [push]
3
3
 
4
- env:
5
- CC_TEST_REPORTER_ID: ${{secrets.CC_TEST_REPORTER_ID}}
6
- # `github.ref` points to the *merge commit* when running tests on a pull request, which will be a commit
7
- # that doesn't exists in our code base. Since this workflow triggers from a PR, we use the HEAD SHA instead.
8
- #
9
- # NOTE: These are both used by Code Climate (cc-test-reporter).
10
- GIT_COMMIT_SHA: ${{github.event.pull_request.head.sha}}
11
- GIT_BRANCH: ${{github.head_ref}}
12
-
13
4
  jobs:
14
5
  lint:
15
6
  runs-on: ubuntu-latest
@@ -38,16 +29,5 @@ jobs:
38
29
  with:
39
30
  ruby-version: ${{ matrix.ruby-version }}
40
31
  bundler-cache: true # runs 'bundle install' and caches installed gems automatically
41
- - name: "Download cc-test-reporter from codeclimate.com"
42
- run: |
43
- curl -L https://codeclimate.com/downloads/test-reporter/test-reporter-latest-linux-amd64 > ./cc-test-reporter
44
- chmod +x ./cc-test-reporter
45
- - name: "Report to Code Climate that we will send a coverage report."
46
- run: ./cc-test-reporter before-build
47
32
  - name: Run tests
48
33
  run: bundle exec rspec
49
- - name: Upload code coverage to Code Climate
50
- run: |
51
- ./cc-test-reporter after-build \
52
- --coverage-input-type simplecov \
53
- ./coverage/.resultset.json
data/.rubocop_todo.yml CHANGED
@@ -80,7 +80,7 @@ Naming/MethodParameterName:
80
80
  # ForbiddenPrefixes: is_, has_, have_
81
81
  # AllowedMethods: is_a?
82
82
  # MethodDefinitionMacros: define_method, define_singleton_method
83
- Naming/PredicateName:
83
+ Naming/PredicatePrefix:
84
84
  Exclude:
85
85
  - 'spec/**/*'
86
86
  - 'lib/daru_lite/data_frame/missable.rb'
data/README.md CHANGED
@@ -4,8 +4,6 @@ Simple, straightforward DataFrames for Ruby
4
4
 
5
5
  [![Build Status](https://github.com/pollandroll/daru_lite/actions/workflows/build.yml/badge.svg)](https://github.com/pollandroll/daru_lite/actions)
6
6
  [![Gem Version](https://img.shields.io/gem/v/daru_lite.svg)](https://rubygems.org/gems/daru_lite)
7
- [![Maintainability](https://api.codeclimate.com/v1/badges/f87d4ed10b5731e50184/maintainability)](https://codeclimate.com/github/pollandroll/daru_lite/maintainability)
8
- [![Test Coverage](https://api.codeclimate.com/v1/badges/f87d4ed10b5731e50184/test_coverage)](https://codeclimate.com/github/pollandroll/daru_lite/test_coverage)
9
7
 
10
8
  ## Introduction
11
9
 
@@ -22,7 +22,10 @@ module DaruLite
22
22
  df = row[*(@index.to_a - other_df.index.to_a)]
23
23
 
24
24
  df = df.concat(other_df)
25
- df.index = DaruLite::Index.new(index)
25
+ df.index = @index.class.public_send(
26
+ @index.is_a?(DaruLite::MultiIndex) ? :from_tuples : :new,
27
+ index
28
+ )
26
29
  df
27
30
  end
28
31
 
@@ -229,7 +229,7 @@ module DaruLite
229
229
  # # 2 false
230
230
  # # 3 false
231
231
  # # 4 true
232
- def is_values(*indexes) # rubocop:disable Naming/PredicateName
232
+ def is_values(*indexes) # rubocop:disable Naming/PredicatePrefix
233
233
  bool_array = @keys.map { |r| indexes.include?(r) }
234
234
  DaruLite::Vector.new(bool_array)
235
235
  end
@@ -122,8 +122,10 @@ module DaruLite
122
122
  end
123
123
 
124
124
  def [](*key)
125
- key.flatten!
126
- if key[0].is_a?(Range)
125
+ if key[0].is_a?(Array)
126
+ collection = key.map { |actual_key| self[*actual_key] }
127
+ collection.one? ? collection.first : collection
128
+ elsif key[0].is_a?(Range)
127
129
  retrieve_from_range(key[0])
128
130
  elsif key[0].is_a?(Integer) && key.size == 1
129
131
  try_retrieve_from_integer(key[0])
@@ -158,15 +160,19 @@ module DaruLite
158
160
 
159
161
  return indexes
160
162
  end
161
- res = self[indexes]
163
+ res = self[*indexes]
162
164
  return res if res.is_a? Integer
163
165
 
164
166
  res.map { |i| self[i] }
165
167
  end
166
168
 
167
169
  def subset(*indexes)
168
- if indexes.first.is_a? Integer
170
+ first_index = indexes.first
171
+ if first_index.is_a? Integer
169
172
  MultiIndex.from_tuples(indexes.map { |index| key(index) })
173
+ elsif first_index.is_a?(Array) && include?(first_index)
174
+ # Same logic as in DaruLite::Index#subset
175
+ MultiIndex.from_tuples indexes
170
176
  else
171
177
  self[indexes].conform indexes
172
178
  end
@@ -15,7 +15,7 @@ module DaruLite
15
15
  end
16
16
 
17
17
  # Returns *true* if an index exists
18
- def has_index?(index) # rubocop:disable Naming/PredicateName
18
+ def has_index?(index) # rubocop:disable Naming/PredicatePrefix
19
19
  @index.include? index
20
20
  end
21
21
 
@@ -4,7 +4,7 @@ module DaruLite
4
4
  extend Gem::Deprecate
5
5
 
6
6
  # Reports whether missing data is present in the Vector.
7
- def has_missing_data? # rubocop:disable Naming/PredicateName
7
+ def has_missing_data? # rubocop:disable Naming/PredicatePrefix
8
8
  !indexes(*DaruLite::MISSING_VALUES).empty?
9
9
  end
10
10
  alias flawed? has_missing_data?
@@ -1,3 +1,3 @@
1
1
  module DaruLite
2
- VERSION = '0.2.0'.freeze
2
+ VERSION = '0.2.1'.freeze
3
3
  end
@@ -41,66 +41,91 @@ shared_examples_for 'a joinable DataFrame' do
41
41
  end
42
42
 
43
43
 
44
- context "#union" do
44
+ describe "#union" do
45
45
  let(:df1) do
46
46
  DaruLite::DataFrame.new({
47
47
  a: [1, 2, 3],
48
- b: [1, 2, 3]},
49
- index: [1,3,5]
48
+ b: [1, 2, 3]}
50
49
  )
51
50
  end
52
51
  let(:df2) do
53
52
  DaruLite::DataFrame.new({
54
53
  a: [4, 5, 6],
55
- c: [4, 5, 6]},
56
- index: [7,9,11]
54
+ c: [4, 5, 6]}
57
55
  )
58
56
  end
59
57
  let(:df3) do
60
58
  DaruLite::DataFrame.new({
61
59
  a: [4, 5, 6],
62
- c: [4, 5, 6]},
63
- index: [5,7,9]
60
+ c: [4, 5, 6]}
64
61
  )
65
62
  end
66
63
 
67
- it 'does not modify the original dataframes' do
68
- df1_a = df1[:a].to_a.dup
69
- df2_a = df2[:a].to_a.dup
70
-
71
- _ = df1.union df2
72
- expect(df1[:a].to_a).to eq df1_a
73
- expect(df2[:a].to_a).to eq df2_a
64
+ shared_examples_for '#union' do
65
+ it 'does not modify the original dataframes' do
66
+ df1_a = df1[:a].to_a.dup
67
+ df2_a = df2[:a].to_a.dup
68
+
69
+ _ = df1.union df2
70
+ expect(df1[:a].to_a).to eq df1_a
71
+ expect(df2[:a].to_a).to eq df2_a
72
+ end
73
+
74
+ it 'creates a new dataframe that is a concatenation of the two dataframe arguments' do
75
+ df1_a = df1[:a].to_a.dup
76
+ df2_a = df2[:a].to_a.dup
77
+
78
+ df_union = df1.union df2
79
+ expect(df_union[:a].to_a).to eq df1_a + df2_a
80
+ end
81
+
82
+ it 'fills in missing vectors with nils' do
83
+ df1_b = df1[:b].to_a.dup
84
+ df2_c = df2[:c].to_a.dup
85
+
86
+ df_union = df1.union df2
87
+ expect(df_union[:b].to_a).to eq df1_b + [nil] * df2.size
88
+ expect(df_union[:c].to_a).to eq [nil] * df1.size + df2_c
89
+ end
90
+
91
+ it 'overwrites part of the first dataframe if there are double indices' do
92
+ vec = DaruLite::Vector.new({a: 4, b: nil, c: 4})
93
+ expect(df1.union(df3).row[df1_df3_common_indice]).to eq vec
94
+ end
95
+
96
+ it 'concats the indices' do
97
+ v1 = df1.index.to_a
98
+ v2 = df2.index.to_a
99
+
100
+ df_union = df1.union df2
101
+ expect(df_union.index.to_a).to eq v1 + v2
102
+ end
74
103
  end
75
104
 
76
- it 'creates a new dataframe that is a concatenation of the two dataframe arguments' do
77
- df1_a = df1[:a].to_a.dup
78
- df2_a = df2[:a].to_a.dup
105
+ context 'with regular index' do
106
+ let(:df1_df3_common_indice) { 5 }
107
+ let(:df2_df3_common_indices) { [7, 9] }
79
108
 
80
- df_union = df1.union df2
81
- expect(df_union[:a].to_a).to eq df1_a + df2_a
82
- end
109
+ before do
110
+ df1.index = [1, 3, df1_df3_common_indice]
111
+ df2.index = [*df2_df3_common_indices, 11]
112
+ df3.index = [df1_df3_common_indice, *df2_df3_common_indices]
113
+ end
83
114
 
84
- it 'fills in missing vectors with nils' do
85
- df1_b = df1[:b].to_a.dup
86
- df2_c = df2[:c].to_a.dup
87
-
88
- df_union = df1.union df2
89
- expect(df_union[:b].to_a).to eq df1_b + [nil] * df2.size
90
- expect(df_union[:c].to_a).to eq [nil] * df1.size + df2_c
115
+ it_behaves_like '#union'
91
116
  end
92
117
 
93
- it 'overwrites part of the first dataframe if there are double indices' do
94
- vec = DaruLite::Vector.new({a: 4, b: nil, c: 4})
95
- expect(df1.union(df3).row[5]).to eq vec
96
- end
118
+ context 'with multi index' do
119
+ let(:df1_df3_common_indice) { [:c, 5] }
120
+ let(:df2_df3_common_indices) { [[:a, 7],[:b, 9]] }
97
121
 
98
- it 'concats the indices' do
99
- v1 = df1.index.to_a
100
- v2 = df2.index.to_a
122
+ before do
123
+ df1.index = DaruLite::MultiIndex.from_tuples([[:a, 1], [:b, 3], df1_df3_common_indice])
124
+ df2.index = DaruLite::MultiIndex.from_tuples([*df2_df3_common_indices, [:c, 11]])
125
+ df3.index = DaruLite::MultiIndex.from_tuples([df1_df3_common_indice, *df2_df3_common_indices])
126
+ end
101
127
 
102
- df_union = df1.union df2
103
- expect(df_union.index.to_a).to eq v1 + v2
128
+ it_behaves_like '#union'
104
129
  end
105
130
  end
106
131
  end
@@ -141,6 +141,10 @@ describe DaruLite::MultiIndex do
141
141
  expect(index[:a, :one, :baz]).to eq(1)
142
142
  end
143
143
 
144
+ it "returns the row numbers when specifying multiple tuples" do
145
+ expect(index[[:a, :one, :baz], [:b, :two, :bar]]).to eq([1, 5])
146
+ end
147
+
144
148
  it "returns MultiIndex when specifying incomplete tuple" do
145
149
  expect(index[:b]).to eq(DaruLite::MultiIndex.from_tuples([
146
150
  [:b,:one,:bar],
@@ -523,6 +527,14 @@ describe DaruLite::MultiIndex do
523
527
  it { is_expected.to eq [0, 1] }
524
528
  end
525
529
 
530
+ context "multiple tuple indexes" do
531
+ subject { idx.pos [:b,:two,:bar], [:b,:one,:foo] }
532
+
533
+ it { is_expected.to be_a Array }
534
+ its(:size) { is_expected.to eq 2 }
535
+ it { is_expected.to eq [1, 3] }
536
+ end
537
+
526
538
  # TODO: Add specs for IndexError
527
539
  end
528
540
 
@@ -552,6 +564,14 @@ describe DaruLite::MultiIndex do
552
564
  its(:to_a) { is_expected.to eq [[:b, :one, :bar], [:b, :two, :bar]] }
553
565
  end
554
566
 
567
+ context "multiple tuple indexes" do
568
+ subject { idx.subset [:b,:two,:bar], [:b,:one,:foo] }
569
+
570
+ it { is_expected.to be_a described_class }
571
+ its(:size) { is_expected.to eq 2 }
572
+ its(:to_a) { is_expected.to eq [[:b,:two,:bar], [:b,:one,:foo]] }
573
+ end
574
+
555
575
  # TODO: Checks for invalid indexes
556
576
  end
557
577
 
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: daru_lite
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.2.0
4
+ version: 0.2.1
5
5
  platform: ruby
6
6
  authors:
7
7
  - Thomas Naude-Filonnière
@@ -545,7 +545,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
545
545
  - !ruby/object:Gem::Version
546
546
  version: '0'
547
547
  requirements: []
548
- rubygems_version: 3.6.8
548
+ rubygems_version: 4.0.4
549
549
  specification_version: 4
550
550
  summary: Data Analysis in RUby, stripped down
551
551
  test_files: