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 CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: 056b93d472f805d8d482c29957bd5d69f7dea651
4
- data.tar.gz: c8bca642cea838cae4ec9629ef999ed69cb9d0dd
3
+ metadata.gz: 01ae8d45320fa67aa7d7ae6b131c777ec2cd88fb
4
+ data.tar.gz: 1cc5bffdfe6f376cc2bbd19c67354c70bec0dd8d
5
5
  SHA512:
6
- metadata.gz: a0da4e097cb7c4621094ac780068c6834d893b1a31b5897269cf9832c5f1aa6b824fb7c85fcda14b0d7baf5e3c6b4ece0036a111ca1eed62a8a7e4fc8f0df5e5
7
- data.tar.gz: c6df181b48f80c7618201549c1858ae531d840a01713d9b1adb47f1ddbae842a3c03e9996175af365ac00c2890ba88dd2d45fd394fdcd4c70f8e33073f1bf352
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
- - 2.4.1
5
- before_install: gem install bundler -v 1.15.4
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
+ [![Build Status](https://travis-ci.org/mrkn/pandas.rb.svg)](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
@@ -0,0 +1,12 @@
1
+ require 'pandas'
2
+
3
+ module Pandas
4
+ class DataFrame
5
+ def [](*key)
6
+ if key.length == 1 && key[0].is_a?(Array)
7
+ key[0] = PyCall::List.new(key[0])
8
+ end
9
+ super
10
+ end
11
+ end
12
+ end
data/lib/pandas/io.rb ADDED
@@ -0,0 +1,11 @@
1
+ require 'pandas'
2
+
3
+ module Pandas
4
+ module IO
5
+ def self.is_activerecord_datasource?(obj)
6
+ return false unless defined?(::ActiveRecord)
7
+ return true if obj.is_a?(::ActiveRecord::ConnectionAdapters::AbstractAdapter)
8
+ false
9
+ end
10
+ end
11
+ end
@@ -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
@@ -1 +1 @@
1
- PANDAS_VERSION = "0.1.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.1.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-07 00:00:00.000000000 Z
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