pandas 0.1.0 → 0.2.0
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/.travis.yml +31 -2
- data/CHANGES.md +15 -0
- data/README.md +2 -0
- data/lib/pandas.rb +41 -0
- data/lib/pandas/data_frame.rb +12 -0
- data/lib/pandas/io.rb +11 -0
- data/lib/pandas/io/active_record.rb +101 -0
- data/lib/pandas/options.rb +17 -0
- data/lib/pandas/version.rb +1 -1
- data/pandas.gemspec +2 -0
- metadata +35 -2
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 01ae8d45320fa67aa7d7ae6b131c777ec2cd88fb
|
4
|
+
data.tar.gz: 1cc5bffdfe6f376cc2bbd19c67354c70bec0dd8d
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 9b2457bd1efb1b291ff11570dd69f3ee9b95b52e4a631993833c962fd83a216e9b08afd52a2a1a41028c541a895ae3678296cd60244d263d91d601a0a8b0966a
|
7
|
+
data.tar.gz: 403ec721bc39c1245b1c82f1255dad2ad8462218b4d48fe30a94fbdba838bff17b124b5e731037c438fdcbdd5806878a166a9cc3dc94c28e4fe4351c5f80ae22
|
data/.travis.yml
CHANGED
@@ -1,5 +1,34 @@
|
|
1
1
|
sudo: false
|
2
2
|
language: ruby
|
3
|
+
|
3
4
|
rvm:
|
4
|
-
-
|
5
|
-
|
5
|
+
- ruby-head
|
6
|
+
- 2.4.0
|
7
|
+
- 2.3.1
|
8
|
+
- 2.2.5
|
9
|
+
- 2.1.10
|
10
|
+
|
11
|
+
addons:
|
12
|
+
apt:
|
13
|
+
packages:
|
14
|
+
- python3
|
15
|
+
- python3-dev
|
16
|
+
- python3-all
|
17
|
+
- python3-all-dev
|
18
|
+
|
19
|
+
env:
|
20
|
+
matrix:
|
21
|
+
- PYTHON=python
|
22
|
+
- LIBPYTHON=/opt/python/3.5.3/lib/libpython3.5m.so
|
23
|
+
|
24
|
+
before_install:
|
25
|
+
- gem update --system
|
26
|
+
- gem update bundler
|
27
|
+
|
28
|
+
before_script:
|
29
|
+
- pip install pandas
|
30
|
+
- pip3 install numpy
|
31
|
+
|
32
|
+
matrix:
|
33
|
+
allow_failures:
|
34
|
+
- env: PYTHON=python # Ignore failed on python 2.7
|
data/CHANGES.md
ADDED
@@ -0,0 +1,15 @@
|
|
1
|
+
# The chenge history of Pandas wrapper for Ruby
|
2
|
+
|
3
|
+
## 0.2.0
|
4
|
+
|
5
|
+
* Support a connection of ActiveRecord in `read_sql_table` and `read_sql_query`
|
6
|
+
|
7
|
+
* Call `register_python_type_mapping` for all wrapper classes
|
8
|
+
|
9
|
+
* Support an array index in `DataFrame#[]`
|
10
|
+
|
11
|
+
* Fix `Pandas.options.display`
|
12
|
+
|
13
|
+
## 0.1.0
|
14
|
+
|
15
|
+
* Define some wrapper classes
|
data/README.md
CHANGED
@@ -1,5 +1,7 @@
|
|
1
1
|
# Pandas wrapper for Ruby
|
2
2
|
|
3
|
+
[](https://travis-ci.org/mrkn/pandas.rb)
|
4
|
+
|
3
5
|
This library enables to directry call [pandas](http://pandas.pydata.org/) from Ruby language.
|
4
6
|
This uses [pycall](https://github.com/mrkn/pycall).
|
5
7
|
|
data/lib/pandas.rb
CHANGED
@@ -7,13 +7,54 @@ module Pandas
|
|
7
7
|
Object.send :remove_const, :PANDAS_VERSION
|
8
8
|
|
9
9
|
DataFrame = self.core.frame.DataFrame
|
10
|
+
DataFrame.__send__ :register_python_type_mapping
|
11
|
+
|
10
12
|
Series = self.core.series.Series
|
13
|
+
Series.__send__ :register_python_type_mapping
|
14
|
+
|
11
15
|
IlocIndexer = self.core.indexing._iLocIndexer
|
16
|
+
IlocIndexer.__send__ :register_python_type_mapping
|
17
|
+
|
12
18
|
LocIndexer = self.core.indexing._LocIndexer
|
19
|
+
LocIndexer.__send__ :register_python_type_mapping
|
20
|
+
|
13
21
|
IXIndexer = self.core.indexing._IXIndexer
|
22
|
+
IXIndexer.__send__ :register_python_type_mapping
|
23
|
+
|
14
24
|
MultiIndex = self.core.indexing.MultiIndex
|
25
|
+
MultiIndex.__send__ :register_python_type_mapping
|
26
|
+
|
15
27
|
DatetimeIndex = self.core.indexes.datetimes.DatetimeIndex
|
28
|
+
DatetimeIndex.__send__ :register_python_type_mapping
|
29
|
+
|
16
30
|
Index = self.core.index.Index
|
31
|
+
Index.__send__ :register_python_type_mapping
|
32
|
+
|
17
33
|
DataFrameGroupBy = self.core.groupby.DataFrameGroupBy
|
34
|
+
DataFrameGroupBy.__send__ :register_python_type_mapping
|
35
|
+
|
18
36
|
SeriesGroupBy = self.core.groupby.SeriesGroupBy
|
37
|
+
SeriesGroupBy.__send__ :register_python_type_mapping
|
38
|
+
|
39
|
+
IO = self.io
|
40
|
+
|
41
|
+
def self.read_sql_table(table_name, conn, *args)
|
42
|
+
if IO.is_activerecord_datasource?(conn)
|
43
|
+
require 'pandas/io/active_record'
|
44
|
+
return IO::Helpers.read_sql_table_from_active_record(table_name, conn, *args)
|
45
|
+
end
|
46
|
+
super
|
47
|
+
end
|
48
|
+
|
49
|
+
def self.read_sql_query(query, conn, *args)
|
50
|
+
if IO.is_activerecord_datasource?(conn)
|
51
|
+
require 'pandas/io/active_record'
|
52
|
+
return IO::Helpers.read_sql_query_from_active_record(query, conn, *args)
|
53
|
+
end
|
54
|
+
super
|
55
|
+
end
|
56
|
+
|
57
|
+
require 'pandas/data_frame'
|
58
|
+
require 'pandas/io'
|
59
|
+
require 'pandas/options'
|
19
60
|
end
|
data/lib/pandas/io.rb
ADDED
@@ -0,0 +1,101 @@
|
|
1
|
+
require 'pandas'
|
2
|
+
require 'active_record'
|
3
|
+
|
4
|
+
module Pandas
|
5
|
+
module IO
|
6
|
+
module Helpers
|
7
|
+
module_function
|
8
|
+
|
9
|
+
def read_sql_table_from_active_record(table_name, conn, *args)
|
10
|
+
case conn
|
11
|
+
when ActiveRecord::ConnectionAdapters::AbstractAdapter
|
12
|
+
read_sql_table_from_active_record_connection(table_name, conn, *args)
|
13
|
+
else
|
14
|
+
raise TypeError, "unexpected type of argument #{conn.class}"
|
15
|
+
end
|
16
|
+
end
|
17
|
+
|
18
|
+
def read_sql_query_from_active_record(query, conn, *args)
|
19
|
+
case conn
|
20
|
+
when ActiveRecord::ConnectionAdapters::AbstractAdapter
|
21
|
+
read_sql_query_from_active_record_connection(query, conn, *args)
|
22
|
+
else
|
23
|
+
raise TypeError, "unexpected type of argument #{conn.class}"
|
24
|
+
end
|
25
|
+
end
|
26
|
+
|
27
|
+
def read_sql_table_from_active_record_connection(table_name, conn, *args)
|
28
|
+
args = parse_read_sql_table_args(*args)
|
29
|
+
index_col, coerce_float, parse_dates, columns, schema, chunksize = *args
|
30
|
+
if columns
|
31
|
+
table_columns = conn.columns(table_name)
|
32
|
+
column_names = columns.select {|c| table_columns.include?(c) }.map do |c|
|
33
|
+
conn.quote_column_name(c.to_s)
|
34
|
+
end
|
35
|
+
else
|
36
|
+
column_names = '*'
|
37
|
+
end
|
38
|
+
query = <<-SQL
|
39
|
+
select #{column_names} from #{conn.quote_table_name(table_name)};
|
40
|
+
SQL
|
41
|
+
# TODO: chunksize
|
42
|
+
result = conn.exec_query(query, 'pandas_sql')
|
43
|
+
data_frame_from_query_result(result, index_col, coerce_float, parse_dates)
|
44
|
+
end
|
45
|
+
|
46
|
+
def read_sql_query_from_active_record_connection(query, conn, *args)
|
47
|
+
args = parse_read_sql_query_args(*args)
|
48
|
+
index_col, coerce_float, parse_dates, chunksize = *args
|
49
|
+
# TODO: chunksize
|
50
|
+
result = conn.exec_query(query, 'pandas_sql')
|
51
|
+
data_frame_from_query_result(result, index_col, coerce_float, parse_dates)
|
52
|
+
end
|
53
|
+
|
54
|
+
def data_frame_from_query_result(result, index_col, coerce_float, parse_dates)
|
55
|
+
records = result.map {|row| row.values }
|
56
|
+
df = Pandas::DataFrame.from_records(
|
57
|
+
records,
|
58
|
+
columns: result.columns,
|
59
|
+
coerce_float: coerce_float
|
60
|
+
)
|
61
|
+
# TODO: self.sql._harmonize_columns(parse_dates: parse_dates)
|
62
|
+
df.set_index(index_col, inplace: true) if index_col
|
63
|
+
df
|
64
|
+
end
|
65
|
+
|
66
|
+
def parse_read_sql_table_args(*args)
|
67
|
+
kwargs = args.pop if args.last.is_a? Hash
|
68
|
+
if kwargs
|
69
|
+
names = [:index_col, :coerce_float, :parse_dates, :columns, :schema, :chunksize]
|
70
|
+
names.each_with_index do |name, index|
|
71
|
+
if kwargs.has_key? name
|
72
|
+
if args[index]
|
73
|
+
warn "#{name} is given as both positional and keyword arguments"
|
74
|
+
else
|
75
|
+
args[index] = kwargs[name]
|
76
|
+
end
|
77
|
+
end
|
78
|
+
end
|
79
|
+
end
|
80
|
+
args
|
81
|
+
end
|
82
|
+
|
83
|
+
def parse_read_sql_query_args(*args)
|
84
|
+
kwargs = args.pop if args.last.is_a? Hash
|
85
|
+
if kwargs
|
86
|
+
names = [:index_col, :coerce_float, :parse_dates, :chunksize]
|
87
|
+
names.each_with_index do |name, index|
|
88
|
+
if kwargs.has_key? name
|
89
|
+
if args[index]
|
90
|
+
warn "#{name} is given as both positional and keyword arguments"
|
91
|
+
else
|
92
|
+
args[index] = kwargs[name]
|
93
|
+
end
|
94
|
+
end
|
95
|
+
end
|
96
|
+
end
|
97
|
+
args
|
98
|
+
end
|
99
|
+
end
|
100
|
+
end
|
101
|
+
end
|
@@ -0,0 +1,17 @@
|
|
1
|
+
module Pandas
|
2
|
+
module OptionsHelper
|
3
|
+
module_function
|
4
|
+
|
5
|
+
def setup_options(options)
|
6
|
+
PyCall::LibPython::Helpers.define_wrapper_method(options, :display)
|
7
|
+
options
|
8
|
+
end
|
9
|
+
end
|
10
|
+
|
11
|
+
def self.options
|
12
|
+
@options ||= begin
|
13
|
+
o = PyCall::LibPython::Helpers.getattr(__pyptr__, :options)
|
14
|
+
OptionsHelper.setup_options(o)
|
15
|
+
end
|
16
|
+
end
|
17
|
+
end
|
data/lib/pandas/version.rb
CHANGED
@@ -1 +1 @@
|
|
1
|
-
PANDAS_VERSION = "0.
|
1
|
+
PANDAS_VERSION = "0.2.0"
|
data/pandas.gemspec
CHANGED
@@ -26,4 +26,6 @@ Gem::Specification.new do |spec|
|
|
26
26
|
spec.add_development_dependency "bundler", "~> 1.15"
|
27
27
|
spec.add_development_dependency "rake", "~> 10.0"
|
28
28
|
spec.add_development_dependency "rspec", "~> 3.0"
|
29
|
+
spec.add_development_dependency "activerecord", ">= 4.2"
|
30
|
+
spec.add_development_dependency "sqlite3"
|
29
31
|
end
|
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: pandas
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.
|
4
|
+
version: 0.2.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Kenta Murata
|
8
8
|
autorequire:
|
9
9
|
bindir: exe
|
10
10
|
cert_chain: []
|
11
|
-
date: 2017-09-
|
11
|
+
date: 2017-09-11 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: pycall
|
@@ -66,6 +66,34 @@ dependencies:
|
|
66
66
|
- - "~>"
|
67
67
|
- !ruby/object:Gem::Version
|
68
68
|
version: '3.0'
|
69
|
+
- !ruby/object:Gem::Dependency
|
70
|
+
name: activerecord
|
71
|
+
requirement: !ruby/object:Gem::Requirement
|
72
|
+
requirements:
|
73
|
+
- - ">="
|
74
|
+
- !ruby/object:Gem::Version
|
75
|
+
version: '4.2'
|
76
|
+
type: :development
|
77
|
+
prerelease: false
|
78
|
+
version_requirements: !ruby/object:Gem::Requirement
|
79
|
+
requirements:
|
80
|
+
- - ">="
|
81
|
+
- !ruby/object:Gem::Version
|
82
|
+
version: '4.2'
|
83
|
+
- !ruby/object:Gem::Dependency
|
84
|
+
name: sqlite3
|
85
|
+
requirement: !ruby/object:Gem::Requirement
|
86
|
+
requirements:
|
87
|
+
- - ">="
|
88
|
+
- !ruby/object:Gem::Version
|
89
|
+
version: '0'
|
90
|
+
type: :development
|
91
|
+
prerelease: false
|
92
|
+
version_requirements: !ruby/object:Gem::Requirement
|
93
|
+
requirements:
|
94
|
+
- - ">="
|
95
|
+
- !ruby/object:Gem::Version
|
96
|
+
version: '0'
|
69
97
|
description: Pandas wrapper for Ruby
|
70
98
|
email:
|
71
99
|
- mrkn@mrkn.jp
|
@@ -76,6 +104,7 @@ files:
|
|
76
104
|
- ".gitignore"
|
77
105
|
- ".rspec"
|
78
106
|
- ".travis.yml"
|
107
|
+
- CHANGES.md
|
79
108
|
- Gemfile
|
80
109
|
- LICENSE.txt
|
81
110
|
- README.md
|
@@ -84,6 +113,10 @@ files:
|
|
84
113
|
- bin/setup
|
85
114
|
- data/titanic.csv
|
86
115
|
- lib/pandas.rb
|
116
|
+
- lib/pandas/data_frame.rb
|
117
|
+
- lib/pandas/io.rb
|
118
|
+
- lib/pandas/io/active_record.rb
|
119
|
+
- lib/pandas/options.rb
|
87
120
|
- lib/pandas/version.rb
|
88
121
|
- pandas.gemspec
|
89
122
|
homepage: https://github.com/mrkn/pandas.rb
|