daru_lite 0.3.1 → 0.3.3

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: 5fd692ae66f7d3b631fc1f2424f823ab3f9484bb8d7803db6ea1405b00bea456
4
- data.tar.gz: 959220244151eddba5fd98abde252d54be976e80cc7e179d8cb3f61a90e3c38d
3
+ metadata.gz: c158868ddcdfad0c071d5ad8b583605e86cdd3a005714df2071d0fc122e88278
4
+ data.tar.gz: 56d1feb6d2b95f6a4c897589c56c32e8890fe72c9eb2e72d6b71a91ffc9e95ae
5
5
  SHA512:
6
- metadata.gz: b4f13fe9ed18e21835c405d40d7241c5d4aea0fb391121c85a504243ac3d755a3b1c1b93f9a78befad060b59e070e234965aff233c3d68d2cac99de9f3280151
7
- data.tar.gz: d084ec8cc01cb06577e686e8abbfe834d9477071342d025a9a8b3033dd43d82d39ec1d1b5d1561fcdf4508f27e3070ea5713604ffe2cb08e419f773792a34d2d
6
+ metadata.gz: 5ac43007818f83995648bdbc65c5debc0d8999c9623271f0d6ca7c70bccc99904b74ec48fd99860a38ad6d02f99493fecdffb6560cbf92fd6a6682eb1190c0a5
7
+ data.tar.gz: 3f980b1dd60846f9aba374663e34fbd0118396079e1366f7e0046c288087adbf0f7f606853dec915dd9b42109f30e2f25033ea277533a711f5be8ab2948e58f3
@@ -107,9 +107,22 @@ module DaruLite
107
107
  end
108
108
 
109
109
  def keep_vector_if
110
- @vectors.each do |vector|
111
- delete_vector(vector) unless yield(@data[@vectors[vector]], vector)
110
+ vector_names = @vectors.to_a
111
+ kept_positions = @vectors.size.times.select do |position|
112
+ yield(@data[position], vector_names[position])
112
113
  end
114
+ kept_names = kept_positions.map { |position| vector_names[position] }
115
+
116
+ @data = kept_positions.map { |position| @data[position] }
117
+ @vectors =
118
+ if @vectors.is_a?(DaruLite::MultiIndex)
119
+ # An empty result can't form a MultiIndex, so it falls back to a plain Index.
120
+ kept_names.any? ? DaruLite::MultiIndex.from_tuples(kept_names) : DaruLite::Index.new(kept_names)
121
+ else
122
+ @vectors.class.new(kept_names)
123
+ end
124
+
125
+ self
113
126
  end
114
127
 
115
128
  # creates a new vector with the data of a given field which the block returns true
@@ -65,6 +65,22 @@ module DaruLite
65
65
  positions.size == 1 ? positions.first : positions.sort
66
66
  end
67
67
 
68
+ # Returns the position(s) of the given category/categories or position(s).
69
+ # Mirrors Index#[] but resolves against the categorical structure
70
+ # (@cat_hash / @array) instead of @relation_hash, which CategoricalIndex
71
+ # never populates.
72
+ # @param keys [Array<object>] categories or positions to look up
73
+ # @return [Integer, Array<Integer>, nil] position(s), or nil if absent
74
+ # @example
75
+ # idx = DaruLite::CategoricalIndex.new [:a, :b, :a]
76
+ # idx[:b] # => 1
77
+ # idx[:z] # => nil
78
+ def [](*keys)
79
+ pos(*keys)
80
+ rescue IndexError
81
+ nil
82
+ end
83
+
68
84
  # Returns index value from position
69
85
  # @param pos [Integer] the position to look for
70
86
  # @return [object] category corresponding to position
@@ -1,3 +1,3 @@
1
1
  module DaruLite
2
- VERSION = '0.3.1'.freeze
2
+ VERSION = '0.3.3'.freeze
3
3
  end
@@ -340,6 +340,53 @@ shared_examples_for 'a filterable DataFrame' do
340
340
  expect(df).to eq(DaruLite::DataFrame.new({a: [1,2,3,4,5]}, order: [:a],
341
341
  index: [:one, :two, :three, :four, :five]))
342
342
  end
343
+
344
+ context "with duplicate tuples in a MultiIndex" do
345
+ let(:multi_index_df) do
346
+ DaruLite::DataFrame.new(
347
+ [[1, 4], [2, 5], [3, 6]],
348
+ order: DaruLite::MultiIndex.from_tuples([[:count, 'A'], [:count, 'A'], [:pct, 'B']]),
349
+ index: %w[r1 r2]
350
+ )
351
+ end
352
+
353
+ it "keeps the matching vectors without raising on the ambiguous lookup" do
354
+ multi_index_df.keep_vector_if { |_vector, (_metric, label)| label != 'B' }
355
+
356
+ expect(multi_index_df.vectors).to be_a(DaruLite::MultiIndex)
357
+ expect(multi_index_df.vectors.to_a).to eq([[:count, 'A'], [:count, 'A']])
358
+ end
359
+
360
+ it "does not raise when no vector is kept" do
361
+ expect { multi_index_df.keep_vector_if { |_vector, _tuple| false } }.not_to raise_error
362
+ expect(multi_index_df.vectors.to_a).to eq([])
363
+ end
364
+ end
365
+
366
+ context "with duplicate categories in a CategoricalIndex" do
367
+ let(:categorical_df) do
368
+ DaruLite::DataFrame.new(
369
+ [[1, 4], [2, 5], [3, 6]],
370
+ order: DaruLite::CategoricalIndex.new([:a, :a, :b]),
371
+ index: %w[r1 r2]
372
+ )
373
+ end
374
+
375
+ it "keeps the matching vectors and preserves the CategoricalIndex" do
376
+ categorical_df.keep_vector_if { |_vector, category| category == :a }
377
+
378
+ expect(categorical_df.vectors).to be_a(DaruLite::CategoricalIndex)
379
+ expect(categorical_df.vectors.to_a).to eq([:a, :a])
380
+ expect(categorical_df.map_vectors(&:to_a)).to eq([[1, 4], [2, 5]])
381
+ end
382
+
383
+ it "preserves the CategoricalIndex when no vector is kept" do
384
+ categorical_df.keep_vector_if { |_vector, _category| false }
385
+
386
+ expect(categorical_df.vectors).to be_a(DaruLite::CategoricalIndex)
387
+ expect(categorical_df.vectors.to_a).to eq([])
388
+ end
389
+ end
343
390
  end
344
391
 
345
392
  describe "#filter_vectors" do
@@ -886,6 +886,23 @@ describe DaruLite::DataFrame do
886
886
  expect(df).to eq(DaruLite::DataFrame.new({b: [11,12,14,15], a: [1,2,4,5],
887
887
  c: [11,22,44,55]}, order: [:a, :b, :c], index: [:one, :two, :four, :five]))
888
888
  end
889
+
890
+ context "when the data frame has a CategoricalIndex" do
891
+ let(:categorical_df) do
892
+ frame = DaruLite::DataFrame.new(
893
+ { a: [1, 2, 3], b: [11, 22, 33] },
894
+ order: [:a, :b],
895
+ index: [:base, :one, :two]
896
+ )
897
+ frame.index = DaruLite::CategoricalIndex.new([:base, :one, :two])
898
+ frame
899
+ end
900
+
901
+ it "deletes the specified row without raising" do
902
+ expect { categorical_df.delete_row :base }.not_to raise_error
903
+ expect(categorical_df.index.to_a).to eq [:one, :two]
904
+ end
905
+ end
889
906
  end
890
907
 
891
908
  context "#rename_vectors!" do
@@ -68,6 +68,38 @@ describe DaruLite::CategoricalIndex do
68
68
  end
69
69
  end
70
70
 
71
+ describe "#[]" do
72
+ context "when the category occurs once" do
73
+ subject { index[:b] }
74
+
75
+ it { is_expected.to eq 1 }
76
+ end
77
+
78
+ context "when the category occurs multiple times" do
79
+ subject { index[:a] }
80
+
81
+ it { is_expected.to eq [0, 2, 3] }
82
+ end
83
+
84
+ context "when given a positional index" do
85
+ subject { index[0] }
86
+
87
+ it { is_expected.to eq 0 }
88
+ end
89
+
90
+ context "when given multiple categories" do
91
+ subject { index[:a, :c] }
92
+
93
+ it { is_expected.to eq [0, 2, 3, 4] }
94
+ end
95
+
96
+ context "when the category is absent" do
97
+ subject { index[:z] }
98
+
99
+ it { is_expected.to be_nil }
100
+ end
101
+ end
102
+
71
103
  context "#subset" do
72
104
  let(:idx) { described_class.new [:a, 1, :a, 1, :c] }
73
105
 
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.3.1
4
+ version: 0.3.3
5
5
  platform: ruby
6
6
  authors:
7
7
  - Thomas Naude-Filonnière
@@ -9,10 +9,9 @@ authors:
9
9
  - Julie Thomas
10
10
  - Amar Slaoua
11
11
  - Mourtada Belhantri
12
- autorequire:
13
12
  bindir: bin
14
13
  cert_chain: []
15
- date: 2026-04-17 00:00:00.000000000 Z
14
+ date: 1980-01-02 00:00:00.000000000 Z
16
15
  dependencies:
17
16
  - !ruby/object:Gem::Dependency
18
17
  name: activerecord
@@ -317,7 +316,6 @@ description: |
317
316
  and can be used with many others like mixed_models, gnuplotrb and iruby.
318
317
 
319
318
  Daru Lite is a fork of Daru that aims to focus on data manipulation and stability.
320
- email:
321
319
  executables: []
322
320
  extensions: []
323
321
  extra_rdoc_files: []
@@ -538,7 +536,6 @@ homepage: https://github.com/pollandroll/daru
538
536
  licenses:
539
537
  - BSD-2-Clause
540
538
  metadata: {}
541
- post_install_message:
542
539
  rdoc_options: []
543
540
  require_paths:
544
541
  - lib
@@ -553,8 +550,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
553
550
  - !ruby/object:Gem::Version
554
551
  version: '0'
555
552
  requirements: []
556
- rubygems_version: 3.4.10
557
- signing_key:
553
+ rubygems_version: 4.0.9
558
554
  specification_version: 4
559
555
  summary: Data Analysis in RUby, stripped down
560
556
  test_files: