daru_lite 0.1.3 → 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 +4 -4
- data/.github/dependabot.yml +11 -0
- data/.github/workflows/ci.yml +2 -22
- data/.rubocop.yml +2 -2
- data/.rubocop_todo.yml +1 -1
- data/README.md +0 -2
- data/benchmarks/db_loading.rb +0 -1
- data/daru_lite.gemspec +10 -12
- data/daru_lite_test-shm +0 -0
- data/daru_lite_test-wal +0 -0
- data/lib/daru_lite/accessors/array_wrapper.rb +4 -4
- data/lib/daru_lite/core/merge.rb +8 -8
- data/lib/daru_lite/data_frame/calculatable.rb +2 -2
- data/lib/daru_lite/data_frame/filterable.rb +4 -4
- data/lib/daru_lite/data_frame/i_o_able.rb +17 -14
- data/lib/daru_lite/data_frame/iterable.rb +11 -11
- data/lib/daru_lite/data_frame/joinable.rb +4 -1
- data/lib/daru_lite/data_frame/queryable.rb +5 -5
- data/lib/daru_lite/dataframe.rb +15 -13
- data/lib/daru_lite/date_time/index.rb +10 -10
- data/lib/daru_lite/extensions/which_dsl.rb +2 -2
- data/lib/daru_lite/index/index.rb +4 -4
- data/lib/daru_lite/index/multi_index.rb +14 -8
- data/lib/daru_lite/io/io.rb +10 -9
- data/lib/daru_lite/io/sql_data_source.rb +7 -24
- data/lib/daru_lite/maths/statistics/dataframe.rb +2 -2
- data/lib/daru_lite/maths/statistics/vector.rb +16 -16
- data/lib/daru_lite/vector/aggregatable.rb +2 -2
- data/lib/daru_lite/vector/filterable.rb +2 -2
- data/lib/daru_lite/vector/indexable.rb +1 -1
- data/lib/daru_lite/vector/missable.rb +1 -1
- data/lib/daru_lite/vector/queryable.rb +4 -4
- data/lib/daru_lite/vector/sortable.rb +4 -4
- data/lib/daru_lite/vector.rb +4 -6
- data/lib/daru_lite/version.rb +1 -1
- data/spec/data_frame/joinable_example.rb +61 -36
- data/spec/index/multi_index_spec.rb +20 -0
- data/spec/io/io_spec.rb +0 -16
- data/spec/io/sql_data_source_spec.rb +0 -8
- data/spec/spec_helper.rb +1 -1
- data/spec/support/database_helper.rb +0 -1
- metadata +30 -65
checksums.yaml
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
---
|
|
2
2
|
SHA256:
|
|
3
|
-
metadata.gz:
|
|
4
|
-
data.tar.gz:
|
|
3
|
+
metadata.gz: 6da8c79960f009b08e12c9d252a267e4d69d6c2152ded63fbe8180891eb25b86
|
|
4
|
+
data.tar.gz: 074d65df9bbc034b37089cf0938a5df45006f8e264ed259721d5823e0ae41c3b
|
|
5
5
|
SHA512:
|
|
6
|
-
metadata.gz:
|
|
7
|
-
data.tar.gz:
|
|
6
|
+
metadata.gz: 56055dcbc442963a8c9881d0b86c767cf9d49d382b1f78b33e7603d83a496028116fef819b38fd15110f67bacccf143354efdba9a919fe829d54006c2e0e6bd5
|
|
7
|
+
data.tar.gz: b3b20cfa80cd6ff336979d1ec836673de99f828883d45186a2762b396ab85ed7b57c8b75709b9ff12623121ed34c707ad66b3ad26aa530e98f43aa5fb27dd4a0
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
# To get started with Dependabot version updates, you'll need to specify which
|
|
2
|
+
# package ecosystems to update and where the package manifests are located.
|
|
3
|
+
# Please see the documentation for all configuration options:
|
|
4
|
+
# https://docs.github.com/code-security/dependabot/dependabot-version-updates/configuration-options-for-the-dependabot.yml-file
|
|
5
|
+
|
|
6
|
+
version: 2
|
|
7
|
+
updates:
|
|
8
|
+
- package-ecosystem: "bundler" # See documentation for possible values
|
|
9
|
+
directory: "/" # Location of package manifests
|
|
10
|
+
schedule:
|
|
11
|
+
interval: "daily"
|
data/.github/workflows/ci.yml
CHANGED
|
@@ -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
|
|
@@ -19,7 +10,7 @@ jobs:
|
|
|
19
10
|
- name: Set up Ruby
|
|
20
11
|
uses: ruby/setup-ruby@v1
|
|
21
12
|
with:
|
|
22
|
-
ruby-version: 3.
|
|
13
|
+
ruby-version: 3.4
|
|
23
14
|
bundler-cache: true # runs 'bundle install' and caches installed gems automatically
|
|
24
15
|
- name: Run linters
|
|
25
16
|
run: |
|
|
@@ -29,7 +20,7 @@ jobs:
|
|
|
29
20
|
runs-on: ubuntu-latest
|
|
30
21
|
strategy:
|
|
31
22
|
matrix:
|
|
32
|
-
ruby-version: ['3.
|
|
23
|
+
ruby-version: ['3.4']
|
|
33
24
|
|
|
34
25
|
steps:
|
|
35
26
|
- uses: actions/checkout@v3
|
|
@@ -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.yml
CHANGED
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/
|
|
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
|
[](https://github.com/pollandroll/daru_lite/actions)
|
|
6
6
|
[](https://rubygems.org/gems/daru_lite)
|
|
7
|
-
[](https://codeclimate.com/github/pollandroll/daru_lite/maintainability)
|
|
8
|
-
[](https://codeclimate.com/github/pollandroll/daru_lite/test_coverage)
|
|
9
7
|
|
|
10
8
|
## Introduction
|
|
11
9
|
|
data/benchmarks/db_loading.rb
CHANGED
data/daru_lite.gemspec
CHANGED
|
@@ -28,29 +28,27 @@ Gem::Specification.new do |spec|
|
|
|
28
28
|
spec.test_files = spec.files.grep(%r{^(test|spec|features)/})
|
|
29
29
|
spec.require_paths = ["lib"]
|
|
30
30
|
|
|
31
|
-
spec.add_development_dependency 'activerecord', '~>
|
|
31
|
+
spec.add_development_dependency 'activerecord', '~> 8.0'
|
|
32
32
|
spec.add_development_dependency 'awesome_print', '~> 1.9.2'
|
|
33
|
-
spec.add_development_dependency 'bundler', '~> 2.
|
|
34
|
-
spec.add_development_dependency '
|
|
35
|
-
spec.add_development_dependency '
|
|
33
|
+
spec.add_development_dependency 'bundler', '~> 2.6'
|
|
34
|
+
spec.add_development_dependency 'csv', '~> 3.3.4'
|
|
35
|
+
spec.add_development_dependency 'debug', '>= 1.0.0'
|
|
36
36
|
spec.add_development_dependency 'distribution', '~> 0.8'
|
|
37
37
|
spec.add_development_dependency 'matrix', '~> 0.4.2'
|
|
38
|
-
spec.add_development_dependency 'nokogiri', '~> 1.
|
|
38
|
+
spec.add_development_dependency 'nokogiri', '~> 1.18.0'
|
|
39
39
|
spec.add_development_dependency 'prime', '~> 0.1.2'
|
|
40
|
-
spec.add_development_dependency 'pry', '~> 0.14'
|
|
41
|
-
spec.add_development_dependency 'pry-byebug', '~> 3.10.1'
|
|
42
40
|
spec.add_development_dependency 'rake', '~> 13.0'
|
|
43
41
|
spec.add_development_dependency 'rspec', '~> 3.11'
|
|
44
|
-
spec.add_development_dependency 'rspec-its', '~>
|
|
42
|
+
spec.add_development_dependency 'rspec-its', '~> 2.0.0'
|
|
45
43
|
spec.add_development_dependency 'rubocop', '~> 1.60'
|
|
46
|
-
spec.add_development_dependency 'rubocop-performance', '~> 1.
|
|
47
|
-
spec.add_development_dependency 'rubocop-rspec', '~>
|
|
44
|
+
spec.add_development_dependency 'rubocop-performance', '~> 1.25.0'
|
|
45
|
+
spec.add_development_dependency 'rubocop-rspec', '~> 3.6'
|
|
48
46
|
spec.add_development_dependency 'ruby-prof', '~> 1.7.0'
|
|
49
47
|
spec.add_development_dependency 'simplecov', '~> 0.22.0'
|
|
50
48
|
spec.add_development_dependency 'simplecov_json_formatter', '~> 0.1.4'
|
|
51
49
|
spec.add_development_dependency 'spreadsheet', '~> 1.3.0'
|
|
52
|
-
spec.add_development_dependency 'sqlite3', '~>
|
|
50
|
+
spec.add_development_dependency 'sqlite3', '~> 2.6.0'
|
|
53
51
|
# issue : https://github.com/SciRuby/daru/issues/493 occured
|
|
54
52
|
# with latest version of sqlite3
|
|
55
|
-
spec.add_development_dependency 'webmock', '~> 3.
|
|
53
|
+
spec.add_development_dependency 'webmock', '~> 3.25.0'
|
|
56
54
|
end
|
data/daru_lite_test-shm
ADDED
|
Binary file
|
data/daru_lite_test-wal
ADDED
|
File without changes
|
data/lib/daru_lite/core/merge.rb
CHANGED
|
@@ -1,6 +1,14 @@
|
|
|
1
1
|
module DaruLite
|
|
2
2
|
module Core
|
|
3
3
|
class MergeFrame
|
|
4
|
+
LEFT_RIGHT_COMBINATIONS = {
|
|
5
|
+
# left right
|
|
6
|
+
inner: [false, false],
|
|
7
|
+
left: [true, false],
|
|
8
|
+
right: [false, true],
|
|
9
|
+
outer: [true, true]
|
|
10
|
+
}.freeze
|
|
11
|
+
|
|
4
12
|
class NilSorter
|
|
5
13
|
include Comparable
|
|
6
14
|
|
|
@@ -55,14 +63,6 @@ module DaruLite
|
|
|
55
63
|
|
|
56
64
|
attr_accessor :merge_key
|
|
57
65
|
|
|
58
|
-
LEFT_RIGHT_COMBINATIONS = {
|
|
59
|
-
# left right
|
|
60
|
-
inner: [false, false],
|
|
61
|
-
left: [true, false],
|
|
62
|
-
right: [false, true],
|
|
63
|
-
outer: [true, true]
|
|
64
|
-
}.freeze
|
|
65
|
-
|
|
66
66
|
def init_opts(opts)
|
|
67
67
|
@on = opts[:on]
|
|
68
68
|
@keep_left, @keep_right = extract_left_right(opts[:how])
|
|
@@ -110,8 +110,8 @@ module DaruLite
|
|
|
110
110
|
# # 4 555
|
|
111
111
|
# # 5 666
|
|
112
112
|
# # 6 777
|
|
113
|
-
def vector_by_calculation(&
|
|
114
|
-
a = each_row.map { |r| r.instance_eval(&
|
|
113
|
+
def vector_by_calculation(&)
|
|
114
|
+
a = each_row.map { |r| r.instance_eval(&) }
|
|
115
115
|
|
|
116
116
|
DaruLite::Vector.new a, index: @index
|
|
117
117
|
end
|
|
@@ -68,8 +68,8 @@ module DaruLite
|
|
|
68
68
|
# df.filter(:row) do |row|
|
|
69
69
|
# row[:a] + row[:d] < 100
|
|
70
70
|
# end
|
|
71
|
-
def filter(axis = :vector, &
|
|
72
|
-
dispatch_to_axis_pl
|
|
71
|
+
def filter(axis = :vector, &)
|
|
72
|
+
dispatch_to_axis_pl(axis, :filter, &)
|
|
73
73
|
end
|
|
74
74
|
|
|
75
75
|
# Returns a dataframe in which rows with any of the mentioned values
|
|
@@ -113,8 +113,8 @@ module DaruLite
|
|
|
113
113
|
end
|
|
114
114
|
|
|
115
115
|
# creates a new vector with the data of a given field which the block returns true
|
|
116
|
-
def filter_vector(vec, &
|
|
117
|
-
DaruLite::Vector.new(each_row.select(&
|
|
116
|
+
def filter_vector(vec, &)
|
|
117
|
+
DaruLite::Vector.new(each_row.select(&).map { |row| row[vec] })
|
|
118
118
|
end
|
|
119
119
|
|
|
120
120
|
# Iterates over each row and retains it in a new DataFrame if the block returns
|
|
@@ -32,8 +32,8 @@ module DaruLite
|
|
|
32
32
|
# :col_sep => ',',
|
|
33
33
|
# :converters => :numeric
|
|
34
34
|
# }
|
|
35
|
-
def from_csv(path, opts = {}, &
|
|
36
|
-
DaruLite::IO.from_csv
|
|
35
|
+
def from_csv(path, opts = {}, &)
|
|
36
|
+
DaruLite::IO.from_csv(path, opts, &)
|
|
37
37
|
end
|
|
38
38
|
|
|
39
39
|
# Read data from an Excel file into a DataFrame.
|
|
@@ -45,28 +45,30 @@ module DaruLite
|
|
|
45
45
|
# == Options
|
|
46
46
|
#
|
|
47
47
|
# *:worksheet_id - ID of the worksheet that is to be read.
|
|
48
|
-
def from_excel(path, opts = {}, &
|
|
49
|
-
DaruLite::IO.from_excel
|
|
48
|
+
def from_excel(path, opts = {}, &)
|
|
49
|
+
DaruLite::IO.from_excel(path, opts, &)
|
|
50
50
|
end
|
|
51
51
|
|
|
52
52
|
# Read a database query and returns a Dataset
|
|
53
53
|
#
|
|
54
|
-
# @param
|
|
54
|
+
# @param arh [ActiveRecord::ConnectionAdapters::AbstractAdapter, String] An ActiveRecord connection
|
|
55
|
+
# OR Path to a SQlite3 database.
|
|
55
56
|
# @param query [String] The query to be executed
|
|
56
57
|
#
|
|
57
58
|
# @return A dataframe containing the data resulting from the query
|
|
58
59
|
#
|
|
59
60
|
# USE:
|
|
60
61
|
#
|
|
61
|
-
#
|
|
62
|
+
# ActiveRecord::Base.establish_connection(adapter: 'sqlite3', database: "path/to/sqlite.db")
|
|
63
|
+
# arh = ActiveRecord::Base.connection
|
|
62
64
|
# DaruLite::DataFrame.from_sql(dbh, "SELECT * FROM test")
|
|
63
65
|
#
|
|
64
66
|
# #Alternatively
|
|
65
67
|
#
|
|
66
|
-
# require '
|
|
68
|
+
# require 'active_record'
|
|
67
69
|
# DaruLite::DataFrame.from_sql("path/to/sqlite.db", "SELECT * FROM test")
|
|
68
|
-
def from_sql(
|
|
69
|
-
DaruLite::IO.from_sql
|
|
70
|
+
def from_sql(arh, query)
|
|
71
|
+
DaruLite::IO.from_sql arh, query
|
|
70
72
|
end
|
|
71
73
|
|
|
72
74
|
# Read a dataframe from AR::Relation
|
|
@@ -149,16 +151,17 @@ module DaruLite
|
|
|
149
151
|
#
|
|
150
152
|
# == Arguments
|
|
151
153
|
#
|
|
152
|
-
# *
|
|
154
|
+
# * arh - ActiveRecord database connection object.
|
|
153
155
|
# * query - Query string.
|
|
154
156
|
#
|
|
155
157
|
# == Usage
|
|
156
158
|
#
|
|
157
159
|
# ds = DaruLite::DataFrame.new({:id=>DaruLite::Vector.new([1,2,3]), :name=>DaruLite::Vector.new(["a","b","c"])})
|
|
158
|
-
#
|
|
159
|
-
#
|
|
160
|
-
|
|
161
|
-
|
|
160
|
+
# ActiveRecord::Base.establish_connection(adapter: 'sqlite3', database: "path/to/sqlite.db")
|
|
161
|
+
# arh = ActiveRecord::Base.connection
|
|
162
|
+
# ds.write_sql(arh,"test")
|
|
163
|
+
def write_sql(arh, table)
|
|
164
|
+
DaruLite::IO.dataframe_write_sql self, arh, table
|
|
162
165
|
end
|
|
163
166
|
|
|
164
167
|
# Use marshalling to save dataframe to a file.
|
|
@@ -68,8 +68,8 @@ module DaruLite
|
|
|
68
68
|
#
|
|
69
69
|
# * +axis+ - The axis to iterate over. Can be :vector (or :column)
|
|
70
70
|
# or :row. Default to :vector.
|
|
71
|
-
def each(axis = :vector, &
|
|
72
|
-
dispatch_to_axis
|
|
71
|
+
def each(axis = :vector, &)
|
|
72
|
+
dispatch_to_axis(axis, :each, &)
|
|
73
73
|
end
|
|
74
74
|
|
|
75
75
|
# Iterate over a row or vector and return results in a DaruLite::Vector.
|
|
@@ -87,8 +87,8 @@ module DaruLite
|
|
|
87
87
|
#
|
|
88
88
|
# * +axis+ - The axis to iterate over. Can be :vector (or :column)
|
|
89
89
|
# or :row. Default to :vector.
|
|
90
|
-
def collect(axis = :vector, &
|
|
91
|
-
dispatch_to_axis_pl
|
|
90
|
+
def collect(axis = :vector, &)
|
|
91
|
+
dispatch_to_axis_pl(axis, :collect, &)
|
|
92
92
|
end
|
|
93
93
|
|
|
94
94
|
# Map over each vector or row of the data frame according to
|
|
@@ -107,8 +107,8 @@ module DaruLite
|
|
|
107
107
|
#
|
|
108
108
|
# * +axis+ - The axis to map over. Can be :vector (or :column) or :row.
|
|
109
109
|
# Default to :vector.
|
|
110
|
-
def map(axis = :vector, &
|
|
111
|
-
dispatch_to_axis_pl
|
|
110
|
+
def map(axis = :vector, &)
|
|
111
|
+
dispatch_to_axis_pl(axis, :map, &)
|
|
112
112
|
end
|
|
113
113
|
|
|
114
114
|
# Destructive map. Modifies the DataFrame. Each run of the block
|
|
@@ -119,11 +119,11 @@ module DaruLite
|
|
|
119
119
|
#
|
|
120
120
|
# * +axis+ - The axis to map over. Can be :vector (or :column) or :row.
|
|
121
121
|
# Default to :vector.
|
|
122
|
-
def map!(axis = :vector, &
|
|
122
|
+
def map!(axis = :vector, &)
|
|
123
123
|
if %i[vector column].include?(axis)
|
|
124
|
-
map_vectors!(&
|
|
124
|
+
map_vectors!(&)
|
|
125
125
|
elsif axis == :row
|
|
126
|
-
map_rows!(&
|
|
126
|
+
map_rows!(&)
|
|
127
127
|
end
|
|
128
128
|
end
|
|
129
129
|
|
|
@@ -144,8 +144,8 @@ module DaruLite
|
|
|
144
144
|
#
|
|
145
145
|
# * +axis+ - The axis to map over. Can be :vector (or :column) or :row.
|
|
146
146
|
# Default to :vector.
|
|
147
|
-
def recode(axis = :vector, &
|
|
148
|
-
dispatch_to_axis_pl
|
|
147
|
+
def recode(axis = :vector, &)
|
|
148
|
+
dispatch_to_axis_pl(axis, :recode, &)
|
|
149
149
|
end
|
|
150
150
|
|
|
151
151
|
# Replace specified values with given value
|
|
@@ -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 =
|
|
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
|
|
|
@@ -31,9 +31,9 @@ module DaruLite
|
|
|
31
31
|
# df.any?(:row) do |row|
|
|
32
32
|
# row[:a] < 3 and row[:b] == 'b'
|
|
33
33
|
# end #=> true
|
|
34
|
-
def any?(axis = :vector, &
|
|
34
|
+
def any?(axis = :vector, &)
|
|
35
35
|
if %i[vector column].include?(axis)
|
|
36
|
-
@data.any?(&
|
|
36
|
+
@data.any?(&)
|
|
37
37
|
elsif axis == :row
|
|
38
38
|
each_row do |row|
|
|
39
39
|
return true if yield(row)
|
|
@@ -53,11 +53,11 @@ module DaruLite
|
|
|
53
53
|
# df.all?(:row) do |row|
|
|
54
54
|
# row[:a] < 10
|
|
55
55
|
# end #=> true
|
|
56
|
-
def all?(axis = :vector, &
|
|
56
|
+
def all?(axis = :vector, &)
|
|
57
57
|
if %i[vector column].include?(axis)
|
|
58
|
-
@data.all?(&
|
|
58
|
+
@data.all?(&)
|
|
59
59
|
elsif axis == :row
|
|
60
|
-
each_row.all?(&
|
|
60
|
+
each_row.all?(&)
|
|
61
61
|
else
|
|
62
62
|
raise ArgumentError, "Unidentified axis #{axis}"
|
|
63
63
|
end
|
data/lib/daru_lite/dataframe.rb
CHANGED
|
@@ -38,6 +38,8 @@ module DaruLite
|
|
|
38
38
|
include DaruLite::Maths::Arithmetic::DataFrame
|
|
39
39
|
include DaruLite::Maths::Statistics::DataFrame
|
|
40
40
|
|
|
41
|
+
AXES = %i[row vector].freeze
|
|
42
|
+
|
|
41
43
|
attr_accessor(*Configuration::INSPECT_OPTIONS_KEYS)
|
|
42
44
|
|
|
43
45
|
extend Gem::Deprecate
|
|
@@ -478,15 +480,17 @@ module DaruLite
|
|
|
478
480
|
self
|
|
479
481
|
end
|
|
480
482
|
|
|
481
|
-
def method_missing(name, *args, &
|
|
482
|
-
|
|
483
|
-
|
|
483
|
+
def method_missing(name, *args, &)
|
|
484
|
+
stringified_name = name.to_s
|
|
485
|
+
|
|
486
|
+
if /^([^=]+)=/.match?(stringified_name)
|
|
487
|
+
name = stringified_name[/^([^=]+)=/].delete('=')
|
|
484
488
|
name = name.to_sym unless has_vector?(name)
|
|
485
489
|
insert_or_modify_vector [name], args[0]
|
|
486
490
|
elsif has_vector?(name)
|
|
487
491
|
self[name]
|
|
488
|
-
elsif has_vector?(
|
|
489
|
-
self[
|
|
492
|
+
elsif has_vector?(stringified_name)
|
|
493
|
+
self[stringified_name]
|
|
490
494
|
else
|
|
491
495
|
super
|
|
492
496
|
end
|
|
@@ -527,28 +531,26 @@ module DaruLite
|
|
|
527
531
|
end
|
|
528
532
|
end
|
|
529
533
|
|
|
530
|
-
def dispatch_to_axis(axis, method,
|
|
534
|
+
def dispatch_to_axis(axis, method, *, &)
|
|
531
535
|
if %i[vector column].include?(axis)
|
|
532
|
-
send(:"#{method}_vector",
|
|
536
|
+
send(:"#{method}_vector", *, &)
|
|
533
537
|
elsif axis == :row
|
|
534
|
-
send(:"#{method}_row",
|
|
538
|
+
send(:"#{method}_row", *, &)
|
|
535
539
|
else
|
|
536
540
|
raise ArgumentError, "Unknown axis #{axis}"
|
|
537
541
|
end
|
|
538
542
|
end
|
|
539
543
|
|
|
540
|
-
def dispatch_to_axis_pl(axis, method,
|
|
544
|
+
def dispatch_to_axis_pl(axis, method, *, &)
|
|
541
545
|
if %i[vector column].include?(axis)
|
|
542
|
-
send(:"#{method}_vectors",
|
|
546
|
+
send(:"#{method}_vectors", *, &)
|
|
543
547
|
elsif axis == :row
|
|
544
|
-
send(:"#{method}_rows",
|
|
548
|
+
send(:"#{method}_rows", *, &)
|
|
545
549
|
else
|
|
546
550
|
raise ArgumentError, "Unknown axis #{axis}"
|
|
547
551
|
end
|
|
548
552
|
end
|
|
549
553
|
|
|
550
|
-
AXES = %i[row vector].freeze
|
|
551
|
-
|
|
552
554
|
def extract_axis(names, default = :vector)
|
|
553
555
|
if AXES.include?(names.last)
|
|
554
556
|
names.pop
|
|
@@ -30,7 +30,7 @@ module DaruLite
|
|
|
30
30
|
(
|
|
31
31
|
(?<offset>MONTH|YEAR|S|H|MB|ME|M|D|YB|YE) |
|
|
32
32
|
(?<offset>W)(-(?<weekday>#{DOW_REGEXP}))?
|
|
33
|
-
)$/x
|
|
33
|
+
)$/x
|
|
34
34
|
|
|
35
35
|
# Generates a DaruLite::DateOffset object for generic offsets or one of the
|
|
36
36
|
# specialized classed within DaruLite::Offsets depending on the 'frequency'
|
|
@@ -131,7 +131,7 @@ module DaruLite
|
|
|
131
131
|
end
|
|
132
132
|
end
|
|
133
133
|
|
|
134
|
-
DATE_PRECISION_REGEXP = /^(\d\d\d\d)(-\d{1,2}(-\d{1,2}( \d{1,2}(:\d{1,2}(:\d{1,2})?)?)?)?)
|
|
134
|
+
DATE_PRECISION_REGEXP = /^(\d\d\d\d)(-\d{1,2}(-\d{1,2}( \d{1,2}(:\d{1,2}(:\d{1,2})?)?)?)?)?$/
|
|
135
135
|
DATE_PRECISIONS = [nil, :year, :month, :day, :hour, :min, :sec].freeze
|
|
136
136
|
|
|
137
137
|
def determine_date_precision_of(date_string)
|
|
@@ -222,8 +222,8 @@ module DaruLite
|
|
|
222
222
|
new(source, freq: :infer) if source && ArrayHelper.array_of?(source, ::DateTime)
|
|
223
223
|
end
|
|
224
224
|
|
|
225
|
-
def each(&
|
|
226
|
-
to_a.each(&
|
|
225
|
+
def each(&)
|
|
226
|
+
to_a.each(&)
|
|
227
227
|
end
|
|
228
228
|
|
|
229
229
|
attr_reader :frequency, :offset, :periods, :keys
|
|
@@ -367,20 +367,20 @@ module DaruLite
|
|
|
367
367
|
end
|
|
368
368
|
end
|
|
369
369
|
|
|
370
|
-
def pos(*
|
|
370
|
+
def pos(*)
|
|
371
371
|
# to filled
|
|
372
|
-
out = self[*
|
|
372
|
+
out = self[*]
|
|
373
373
|
return out if out.is_a? Numeric
|
|
374
374
|
|
|
375
375
|
out.map { |date| self[date] }
|
|
376
376
|
end
|
|
377
377
|
|
|
378
|
-
def subset(*
|
|
379
|
-
self[*
|
|
378
|
+
def subset(*)
|
|
379
|
+
self[*]
|
|
380
380
|
end
|
|
381
381
|
|
|
382
|
-
def valid?(*
|
|
383
|
-
self[*
|
|
382
|
+
def valid?(*)
|
|
383
|
+
self[*]
|
|
384
384
|
true
|
|
385
385
|
rescue IndexError
|
|
386
386
|
false
|
|
@@ -12,8 +12,8 @@ module DaruLite
|
|
|
12
12
|
# df.which{ (`NameTitle` == 'Dr') & (`Sex` == 'female') }
|
|
13
13
|
# equals
|
|
14
14
|
# df.where( df['NameTitle'].eq('Dr') & df['Sex'].eq('female') )
|
|
15
|
-
def which(&
|
|
16
|
-
WhichQuery.new(self, &
|
|
15
|
+
def which(&)
|
|
16
|
+
WhichQuery.new(self, &).exec
|
|
17
17
|
end
|
|
18
18
|
end
|
|
19
19
|
|
|
@@ -20,7 +20,7 @@ module DaruLite
|
|
|
20
20
|
|
|
21
21
|
# We over-ride the .new method so that any sort of Index can be generated
|
|
22
22
|
# from DaruLite::Index based on the types of arguments supplied.
|
|
23
|
-
def self.new(*args, &
|
|
23
|
+
def self.new(*args, &)
|
|
24
24
|
# FIXME: I'm not sure this clever trick really deserves our attention.
|
|
25
25
|
# Most of common ruby libraries just avoid it in favor of usual
|
|
26
26
|
# factor method, like `Index.create`. When `Index.new(...).class != Index`
|
|
@@ -29,7 +29,7 @@ module DaruLite
|
|
|
29
29
|
|
|
30
30
|
MultiIndex.try_from_tuples(source) ||
|
|
31
31
|
DateTimeIndex.try_create(source) ||
|
|
32
|
-
allocate.tap { |i| i.send
|
|
32
|
+
allocate.tap { |i| i.send(:initialize, *args, &) }
|
|
33
33
|
end
|
|
34
34
|
|
|
35
35
|
def self.coerce(maybe_index)
|
|
@@ -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/
|
|
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
|
|
@@ -377,7 +377,7 @@ module DaruLite
|
|
|
377
377
|
def numeric_pos(key)
|
|
378
378
|
if @relation_hash.key?(key)
|
|
379
379
|
@relation_hash[key]
|
|
380
|
-
elsif key.is_a?(Numeric) &&
|
|
380
|
+
elsif key.is_a?(Numeric) && key < size && key >= -size
|
|
381
381
|
key
|
|
382
382
|
else
|
|
383
383
|
raise IndexError, "Specified index #{key.inspect} does not exist"
|
|
@@ -1,11 +1,11 @@
|
|
|
1
1
|
module DaruLite
|
|
2
2
|
class MultiIndex < Index # rubocop:disable Metrics/ClassLength
|
|
3
|
-
def each(&
|
|
4
|
-
to_a.each(&
|
|
3
|
+
def each(&)
|
|
4
|
+
to_a.each(&)
|
|
5
5
|
end
|
|
6
6
|
|
|
7
|
-
def map(&
|
|
8
|
-
to_a.map(&
|
|
7
|
+
def map(&)
|
|
8
|
+
to_a.map(&)
|
|
9
9
|
end
|
|
10
10
|
|
|
11
11
|
attr_reader :labels, :name
|
|
@@ -122,8 +122,10 @@ module DaruLite
|
|
|
122
122
|
end
|
|
123
123
|
|
|
124
124
|
def [](*key)
|
|
125
|
-
key.
|
|
126
|
-
|
|
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
|
-
|
|
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
|