pandas 0.1.0 → 0.2.0

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
  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