charty 0.2.10 → 0.2.12

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: d885d476eadfadd3f76f138707ffaf6166eec006b4528fb19c3acce0b97b1c85
4
- data.tar.gz: 0630f23f19b65177f3b6dc238717a81a019f9dfa40a40c143d71dcc5c5f760f0
3
+ metadata.gz: ab62fdc14b2c1b6410bea925353cdb6fbd7b25d4bf81e007dad99aa5f0dd1976
4
+ data.tar.gz: d61cced997d48a2b5c26e2867a96dfc53be97e5c6c0eb85f323a11d1257a2ef6
5
5
  SHA512:
6
- metadata.gz: 535a69b8d794ccbd30b4328f3188c8a8b50c850cfd84285f79b31162296a9d981313e561ea1089a68be3368b7eb1c83ccc3cb2ff511b8f79aef77e544e261bbe
7
- data.tar.gz: 804de2468433db38b5381bcbccab4c28e84c7592bce5c5a98a539ce99c589449759e65ffe7f2e808bd3c5cb5e002ee2219219111561f66f590dbb0ac2c0757bc
6
+ metadata.gz: 198e8dc2bf17033af0b124a1fbca82d2c29efde9bdaf55fb9bc57bc1184e66e0f7bd8268edfb4c13d90b46f20d955f65760db168010c5ec886c30f53f59db45d
7
+ data.tar.gz: 605dea2aab3c7633a1a3ef3351cc48f0e1f507da4993f529286c0ef0cf2b69cae7b666d22b4e4a7a993f69a9177ed441766983e6e4e9cd2e909f17f1ebbeff49
@@ -62,6 +62,8 @@ jobs:
62
62
 
63
63
  - run: sudo apt install build-essential libsqlite3-dev
64
64
 
65
+ - run: npm install playwright@latest
66
+
65
67
  - run: bundle install --jobs 4 --retry 3 --without "nmatrix python"
66
68
 
67
69
  - run: bundle exec rake
@@ -58,6 +58,8 @@ jobs:
58
58
 
59
59
  - run: sudo apt install build-essential libsqlite3-dev
60
60
 
61
+ - run: npm install playwright@latest
62
+
61
63
  - run: bundle install --jobs 4 --retry 3 --without "numo python"
62
64
 
63
65
  - run: bundle exec rake
@@ -74,6 +74,8 @@ jobs:
74
74
 
75
75
  - run: sudo apt install build-essential libsqlite3-dev
76
76
 
77
+ - run: npm install playwright@latest
78
+
77
79
  - run: pip install --user matplotlib pandas
78
80
 
79
81
  - run: bundle install --jobs 4 --retry 3 --without "nmatrix numo"
@@ -309,8 +309,8 @@ module Charty
309
309
 
310
310
  groups = (0 ... x.length).group_by do |i|
311
311
  key = {}
312
- key[:color] = color[i] unless color.nil?
313
- key[:style] = style[i] unless style.nil?
312
+ key[:color] = color.iloc(i) unless color.nil?
313
+ key[:style] = style.iloc(i) unless style.nil?
314
314
  key
315
315
  end
316
316
 
@@ -20,12 +20,12 @@ module Charty
20
20
  @figure = {
21
21
  type: :bar,
22
22
  bar_pos: bar_pos,
23
- values: values
23
+ values: values,
24
24
  }
25
25
  end
26
26
 
27
- def box_plot(plot_data, positions, **kwargs)
28
- @figure = { type: :box, data: plot_data }
27
+ def box_plot(plot_data, positions, orient:, **kwargs)
28
+ @figure = { type: :box, data: plot_data, orient: orient }
29
29
  end
30
30
 
31
31
  def set_xlabel(label)
@@ -57,7 +57,12 @@ module Charty
57
57
  when :bar
58
58
  ::UnicodePlot.barplot(@layout[:xtick_labels], @figure[:values], xlabel: @layout[:xlabel])
59
59
  when :box
60
- ::UnicodePlot.boxplot(@layout[:xtick_labels], @figure[:data], xlabel: @layout[:xlabel])
60
+ xlabel = if @figure[:orient] == :v
61
+ @layout[:ylabel]
62
+ else
63
+ @layout[:xlabel]
64
+ end
65
+ ::UnicodePlot.boxplot(@layout[:xtick_labels], @figure[:data], xlabel: xlabel)
61
66
  end
62
67
  sio = StringIO.new
63
68
  class << sio
data/lib/charty/index.rb CHANGED
@@ -199,6 +199,15 @@ module Charty
199
199
  end
200
200
  end
201
201
 
202
+ def loc(key)
203
+ case values
204
+ when Pandas::Index
205
+ values.get_loc(key)
206
+ else
207
+ super
208
+ end
209
+ end
210
+
202
211
  def union(other)
203
212
  other = PandasIndex.try_convert(other)
204
213
  # NOTE: Using `sort=False` in pandas.Index#union does not produce pandas.RangeIndex.
@@ -8,13 +8,17 @@ module Charty
8
8
  end
9
9
 
10
10
  def each(&block)
11
- step = (@range.end - @range.begin).to_r / (@num_step - 1)
12
- (@num_step - 1).times do |i|
13
- block.call(@range.begin + i * step)
14
- end
11
+ if @num_step == 1
12
+ block.call(@range.begin)
13
+ else
14
+ step = (@range.end - @range.begin).to_r / (@num_step - 1)
15
+ (@num_step - 1).times do |i|
16
+ block.call(@range.begin + i * step)
17
+ end
15
18
 
16
- unless @range.exclude_end?
17
- block.call(@range.end)
19
+ unless @range.exclude_end?
20
+ block.call(@range.end)
21
+ end
18
22
  end
19
23
  end
20
24
  end
@@ -185,7 +185,7 @@ module Charty
185
185
  elsif vector.categorical?
186
186
  :categorical
187
187
  else
188
- case vector[0]
188
+ case vector.iloc(0)
189
189
  when true, false
190
190
  boolean_type
191
191
  else
@@ -109,9 +109,9 @@ module Charty
109
109
  a = a.sort
110
110
  n = a.size
111
111
  q.map do |x|
112
- x = n * (x / 100.0)
112
+ x = (n-1) * (x / 100.0)
113
113
  i = x.floor
114
- if i == n-1
114
+ if i == x
115
115
  a[i]
116
116
  else
117
117
  t = x - i
@@ -0,0 +1,53 @@
1
+ module Charty
2
+ module TableAdapters
3
+ class ArrowAdapter < BaseAdapter
4
+ TableAdapters.register(:arrow, self)
5
+
6
+ def self.supported?(data)
7
+ defined?(Arrow::Table) && data.is_a?(Arrow::Table)
8
+ end
9
+
10
+ def initialize(data)
11
+ @data = data
12
+ @column_names = @data.columns.map(&:name)
13
+ self.columns = Index.new(@column_names)
14
+ self.index = RangeIndex.new(0 ... length)
15
+ end
16
+
17
+ attr_reader :data
18
+
19
+ def length
20
+ @data.n_rows
21
+ end
22
+
23
+ def column_length
24
+ @column_names.length
25
+ end
26
+
27
+ def compare_data_equality(other)
28
+ case other
29
+ when ArrowAdapter
30
+ data == other.data
31
+ else
32
+ super
33
+ end
34
+ end
35
+
36
+ def [](row, column)
37
+ if row
38
+ @data[column][row]
39
+ else
40
+ case column
41
+ when Array
42
+ Table.new(@data.select_columns(*column))
43
+ else
44
+ column_data = @data[column]
45
+ Vector.new(column_data.data.combine,
46
+ index: index,
47
+ name: column_data.name)
48
+ end
49
+ end
50
+ end
51
+ end
52
+ end
53
+ end
@@ -75,6 +75,8 @@ module Charty
75
75
  arrays[i] << record[key]
76
76
  end
77
77
  end
78
+ when Vector
79
+ arrays = data
78
80
  when self.class.method(:array?)
79
81
  unsupported_data_format unless data.all?(&self.class.method(:array?))
80
82
  arrays = data.map(&:to_a).transpose
@@ -121,20 +123,15 @@ module Charty
121
123
  index = union_indexes(*indexes)
122
124
 
123
125
  arrays = arrays.map do |array|
124
- case array
125
- when Charty::Vector
126
- array.data
127
- when Hash
128
- raise NotImplementedError
129
- when self.class.method(:array?)
130
- array
131
- else
132
- Array.try_convert(array)
133
- end
126
+ Vector.try_convert(array)
134
127
  end
135
128
 
136
129
  columns = generate_column_names(arrays.length, columns)
137
130
 
131
+ arrays.zip(columns) do |array, column|
132
+ array.name = column.to_sym if array.name.to_s != column
133
+ end
134
+
138
135
  return arrays, columns, index
139
136
  end
140
137
 
@@ -199,9 +196,7 @@ module Charty
199
196
  else
200
197
  @data[str_key]
201
198
  end
202
- # FIXME: Here column_data need to be dupped to
203
- # prevent to overwrite the name of Pandas::Series
204
- Vector.new(column_data.dup, index: index, name: column)
199
+ Vector.new(column_data, index: index, name: column)
205
200
  end
206
201
  end
207
202
 
@@ -216,15 +211,10 @@ module Charty
216
211
  end
217
212
 
218
213
  orig_values = values
219
- case values
220
- when Charty::Vector
221
- values = values.data
222
- else
223
- values = Array.try_convert(values)
224
- end
214
+ values = Vector.try_convert(values)
225
215
  if values.nil?
226
216
  raise ArgumentError,
227
- "`values` must be convertible to Array"
217
+ "`values` must be convertible to Charty::Vector"
228
218
  end
229
219
 
230
220
  if values.length != self.length
@@ -23,3 +23,4 @@ require_relative 'table_adapters/daru_adapter'
23
23
  require_relative 'table_adapters/active_record_adapter'
24
24
  require_relative 'table_adapters/nmatrix_adapter'
25
25
  require_relative 'table_adapters/pandas_adapter'
26
+ require_relative 'table_adapters/arrow_adapter'
data/lib/charty/vector.rb CHANGED
@@ -34,6 +34,7 @@ module Charty
34
34
 
35
35
  alias size length
36
36
 
37
+ def_delegators :adapter, :iloc
37
38
  def_delegators :adapter, :to_a
38
39
  def_delegators :adapter, :each
39
40
  def_delegators :adapter, :empty?
@@ -49,7 +50,7 @@ module Charty
49
50
 
50
51
  alias completecases notnull
51
52
 
52
- def_delegators :adapter, :mean, :stdev
53
+ def_delegators :adapter, :mean, :stdev, :percentile
53
54
 
54
55
  def_delegators :adapter, :scale, :scale_inverse
55
56
 
@@ -30,7 +30,7 @@ module Charty
30
30
  include NameSupport
31
31
  include IndexSupport
32
32
 
33
- def_delegators :data, :values_at
33
+ def_delegators :data, :values_at, :to_a
34
34
 
35
35
  def where(mask)
36
36
  masked_data, masked_index = where_in_array(mask)
@@ -0,0 +1,156 @@
1
+ module Charty
2
+ module VectorAdapters
3
+ class ArrowAdapter < BaseAdapter
4
+ VectorAdapters.register(:arrow, self)
5
+
6
+ include Enumerable
7
+ include NameSupport
8
+ include IndexSupport
9
+
10
+ def self.supported?(data)
11
+ (defined?(Arrow::Array) && data.is_a?(Arrow::Array)) ||
12
+ (defined?(Arrow::ChunkedArray) && data.is_a?(Arrow::ChunkedArray))
13
+ end
14
+
15
+ def initialize(data)
16
+ @data = check_data(data)
17
+ self.index = index || RangeIndex.new(0 ... length)
18
+ end
19
+
20
+ def size
21
+ @data.length
22
+ end
23
+
24
+ def empty?
25
+ @data.length.zero?
26
+ end
27
+
28
+ def where(mask)
29
+ mask = check_mask_vector(mask)
30
+ mask_data = mask.data
31
+ unless mask_data.is_a?(Arrow::BooleanArray)
32
+ mask_data = mask.to_a
33
+ mask_data = mask_data.map(&:nonzero?) if mask_data[0].is_a?(Integer)
34
+ mask_data = Arrow::BooleanArray.new(mask_data)
35
+ end
36
+ masked_data = @data.filter(mask_data)
37
+ masked_index = []
38
+ mask_data.to_a.each_with_index do |boolean, i|
39
+ masked_index << index[i] if boolean
40
+ end
41
+ Vector.new(masked_data, index: masked_index, name: name)
42
+ end
43
+
44
+ def boolean?
45
+ case @data
46
+ when Arrow::BooleanArray
47
+ true
48
+ when Arrow::ChunkedArray
49
+ @data.value_data_type.is_a?(Arrow::BooleanDataType)
50
+ else
51
+ false
52
+ end
53
+ end
54
+
55
+ def numeric?
56
+ case @data
57
+ when Arrow::NumericArray
58
+ true
59
+ when Arrow::ChunkedArray
60
+ @data.value_data_type.is_a?(Arrow::NumericDataType)
61
+ else
62
+ false
63
+ end
64
+ end
65
+
66
+ def categorical?
67
+ case @data
68
+ when Arrow::StringArray, Arrow::DictionaryArray
69
+ true
70
+ when Arrow::ChunkedArray
71
+ case @data.value_data_type
72
+ when Arrow::StringArray, Arrow::DictionaryDataType
73
+ true
74
+ else
75
+ false
76
+ end
77
+ else
78
+ false
79
+ end
80
+ end
81
+
82
+ def categories
83
+ if @data.respond_to?(:dictionary)
84
+ dictionary = @data.dictionary
85
+ else
86
+ dictionary = @data.dictionary_encode.dictionary
87
+ end
88
+ dictionary.to_a
89
+ end
90
+
91
+ def unique_values
92
+ @data.unique.to_a
93
+ end
94
+
95
+ def group_by(grouper)
96
+ grouper = Vector.new(grouper) unless grouper.is_a?(Vector)
97
+ group_keys = grouper.unique_values
98
+ grouper_data = grouper.data
99
+ unless grouper_data.is_a?(Arrow::Array)
100
+ grouper_data = Arrow::Array.new(grouper.to_a)
101
+ end
102
+ equal = Arrow::Function.find("equal")
103
+ group_keys.map { |key|
104
+ if key.nil?
105
+ target_vector = Vector.new([nil] * @data.n_nulls)
106
+ else
107
+ mask = equal.execute([grouper_data, key]).value
108
+ target_vector = Vector.new(@data.filter(mask))
109
+ end
110
+ [key, target_vector]
111
+ }.to_h
112
+ end
113
+
114
+ def drop_na
115
+ if @data.n_nulls.zero?
116
+ Vector.new(@data, index: index, name: name)
117
+ else
118
+ data_without_null =
119
+ Arrow::Function.find("drop_null").execute([@data]).value
120
+ Vector.new(data_without_null)
121
+ end
122
+ end
123
+
124
+ def eq(val)
125
+ mask = Arrow::Function.find("equal").execute([@data, val]).value
126
+ Vector.new(mask, index: index, name: name)
127
+ end
128
+
129
+ def notnull
130
+ if @data.n_nulls.zero?
131
+ mask = Arrow::BooleanArray.new([true] * @data.length)
132
+ else
133
+ mask = Arrow::BooleanArray.new(@data.length,
134
+ @data.null_bitmap,
135
+ nil,
136
+ 0)
137
+ end
138
+ Vector.new(mask, index: index, name: name)
139
+ end
140
+
141
+ def mean
142
+ @data.mean
143
+ end
144
+
145
+ def stdev(population: false)
146
+ options = Arrow::VarianceOptions.new
147
+ if population
148
+ options.ddof = 0
149
+ else
150
+ options.ddof = 1
151
+ end
152
+ Arrow::Function.find("stddev").execute([@data], options).value.value
153
+ end
154
+ end
155
+ end
156
+ end
@@ -34,12 +34,8 @@ module Charty
34
34
  case other
35
35
  when DaruVectorAdapter
36
36
  data == other.data
37
- when ArrayAdapter
38
- data.to_a == other.data
39
- when NArrayAdapter, NMatrixAdapter, NumpyAdapter, PandasSeriesAdapter
40
- other.compare_data_equality(self)
41
37
  else
42
- data == other.data.to_a
38
+ to_a == other.to_a
43
39
  end
44
40
  end
45
41
 
@@ -156,7 +152,8 @@ module Charty
156
152
  end
157
153
 
158
154
  def percentile(q)
159
- data.linear_percentile(q)
155
+ a = data.reject_values(*Daru::MISSING_VALUES).to_a
156
+ Statistics.percentile(a, q)
160
157
  end
161
158
  end
162
159
  end
@@ -22,13 +22,22 @@ module Charty
22
22
  when NumpyAdapter, PandasSeriesAdapter
23
23
  other.compare_data_equality(self)
24
24
  else
25
- data == other.data.to_a
25
+ data == other.to_a
26
26
  end
27
27
  end
28
28
 
29
29
  include NameSupport
30
30
  include IndexSupport
31
31
 
32
+ def to_a
33
+ case data
34
+ when Numo::Bit
35
+ map {|bit| bit == 1 }
36
+ else
37
+ super
38
+ end
39
+ end
40
+
32
41
  def where(mask)
33
42
  mask = check_mask_vector(mask)
34
43
  case mask.data
@@ -19,12 +19,8 @@ module Charty
19
19
  case other
20
20
  when NMatrixAdapter
21
21
  data == other.data
22
- when ArrayAdapter, DaruVectorAdapter
23
- data.to_a == other.data.to_a
24
- when NArrayAdapter, NumpyAdapter, PandasSeriesAdapter
25
- other.compare_data_equality(self)
26
22
  else
27
- data == other.data.to_a
23
+ data.to_a == other.data.to_a
28
24
  end
29
25
  end
30
26
 
@@ -163,6 +163,10 @@ module Charty
163
163
  def stdev(population: false)
164
164
  Numpy.std(data, ddof: population ? 0 : 1)
165
165
  end
166
+
167
+ def percentile(q)
168
+ Numpy.nanpercentile(data, q)
169
+ end
166
170
  end
167
171
  end
168
172
  end
@@ -61,6 +61,10 @@ module Charty
61
61
  data.equals(Pandas::Series.new(other, index: data.index))
62
62
  end
63
63
 
64
+ def iloc(i)
65
+ data.iloc[i]
66
+ end
67
+
64
68
  def [](key)
65
69
  case key
66
70
  when Charty::Vector
@@ -0,0 +1,63 @@
1
+ module Charty
2
+ module VectorAdapters
3
+ class VectorAdapter < BaseAdapter
4
+ VectorAdapters.register(:vector, self)
5
+
6
+ extend Forwardable
7
+ include Enumerable
8
+
9
+ def self.supported?(data)
10
+ data.is_a?(Vector)
11
+ end
12
+
13
+ def initialize(data, index: nil)
14
+ data = check_data(data)
15
+ @data = reduce_nested_vector(data)
16
+ self.index = index || RangeIndex.new(0 ... length)
17
+ end
18
+
19
+ include NameSupport
20
+ include IndexSupport
21
+
22
+ def_delegators :data,
23
+ :boolean?,
24
+ :categorical?,
25
+ :categories,
26
+ :drop_na,
27
+ :each,
28
+ :eq,
29
+ :first_nonnil,
30
+ :group_by,
31
+ :notnull,
32
+ :numeric?,
33
+ :to_a,
34
+ :uniq,
35
+ :unique_values,
36
+ :values_at,
37
+ :where,
38
+ :iloc
39
+
40
+ def compare_data_equality(other)
41
+ if other.is_a?(self.class)
42
+ other = reduce_nested_vector(other.data).adapter
43
+ end
44
+ if other.is_a?(self.class)
45
+ @data.adapter.data == other.data
46
+ elsif @data.adapter.respond_to?(:compare_data_equality)
47
+ @data.adapter.compare_data_equality(other)
48
+ elsif other.respond_to?(:compare_data_equality)
49
+ other.compare_data_equality(@data.adapter)
50
+ else
51
+ @data.adapter.to_a == other.to_a
52
+ end
53
+ end
54
+
55
+ private def reduce_nested_vector(vector)
56
+ while vector.adapter.is_a?(self.class)
57
+ vector = vector.adapter.data
58
+ end
59
+ vector
60
+ end
61
+ end
62
+ end
63
+ end
@@ -57,6 +57,8 @@ module Charty
57
57
  end
58
58
  end
59
59
 
60
+ def_delegator :data, :[], :iloc
61
+
60
62
  def_delegators :data, :[], :[]=
61
63
  def_delegators :data, :each, :to_a, :empty?
62
64
 
@@ -100,6 +102,10 @@ module Charty
100
102
  Statistics.stdev(data, population: population)
101
103
  end
102
104
 
105
+ def percentile(q)
106
+ Statistics.percentile(data, q)
107
+ end
108
+
103
109
  def log_scale(method)
104
110
  Charty::Vector.new(
105
111
  self.map {|x| Math.log10(x) },
@@ -144,7 +150,7 @@ module Charty
144
150
  when Charty::Vector
145
151
  where(key)
146
152
  else
147
- super(key_to_loc(key))
153
+ iloc(key_to_loc(key))
148
154
  end
149
155
  end
150
156
 
@@ -196,8 +202,10 @@ module Charty
196
202
  end
197
203
 
198
204
  require_relative "vector_adapters/array_adapter"
205
+ require_relative "vector_adapters/arrow_adapter"
199
206
  require_relative "vector_adapters/daru_adapter"
200
207
  require_relative "vector_adapters/narray_adapter"
201
208
  require_relative "vector_adapters/nmatrix_adapter"
202
209
  require_relative "vector_adapters/numpy_adapter"
203
210
  require_relative "vector_adapters/pandas_adapter"
211
+ require_relative "vector_adapters/vector_adapter"
@@ -1,5 +1,5 @@
1
1
  module Charty
2
- VERSION = "0.2.10"
2
+ VERSION = "0.2.12"
3
3
 
4
4
  module Version
5
5
  numbers, TAG = VERSION.split("-")
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: charty
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.2.10
4
+ version: 0.2.12
5
5
  platform: ruby
6
6
  authors:
7
7
  - youchan
@@ -10,7 +10,7 @@ authors:
10
10
  autorequire:
11
11
  bindir: exe
12
12
  cert_chain: []
13
- date: 2021-08-18 00:00:00.000000000 Z
13
+ date: 2022-10-02 00:00:00.000000000 Z
14
14
  dependencies:
15
15
  - !ruby/object:Gem::Dependency
16
16
  name: red-colors
@@ -336,6 +336,7 @@ files:
336
336
  - lib/charty/table.rb
337
337
  - lib/charty/table_adapters.rb
338
338
  - lib/charty/table_adapters/active_record_adapter.rb
339
+ - lib/charty/table_adapters/arrow_adapter.rb
339
340
  - lib/charty/table_adapters/base_adapter.rb
340
341
  - lib/charty/table_adapters/daru_adapter.rb
341
342
  - lib/charty/table_adapters/datasets_adapter.rb
@@ -347,11 +348,13 @@ files:
347
348
  - lib/charty/vector.rb
348
349
  - lib/charty/vector_adapters.rb
349
350
  - lib/charty/vector_adapters/array_adapter.rb
351
+ - lib/charty/vector_adapters/arrow_adapter.rb
350
352
  - lib/charty/vector_adapters/daru_adapter.rb
351
353
  - lib/charty/vector_adapters/narray_adapter.rb
352
354
  - lib/charty/vector_adapters/nmatrix_adapter.rb
353
355
  - lib/charty/vector_adapters/numpy_adapter.rb
354
356
  - lib/charty/vector_adapters/pandas_adapter.rb
357
+ - lib/charty/vector_adapters/vector_adapter.rb
355
358
  - lib/charty/version.rb
356
359
  homepage: https://github.com/red-data-tools/charty
357
360
  licenses:
@@ -372,7 +375,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
372
375
  - !ruby/object:Gem::Version
373
376
  version: '0'
374
377
  requirements: []
375
- rubygems_version: 3.2.23
378
+ rubygems_version: 3.3.13
376
379
  signing_key:
377
380
  specification_version: 4
378
381
  summary: Visualizing your data in a simple way.