polars-df 0.1.2 → 0.1.3
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/.yardopts +3 -0
- data/CHANGELOG.md +4 -0
- data/Cargo.lock +2 -1
- data/README.md +1 -1
- data/ext/polars/Cargo.toml +7 -1
- data/ext/polars/src/conversion.rs +35 -2
- data/ext/polars/src/dataframe.rs +228 -11
- data/ext/polars/src/lazy/dataframe.rs +3 -3
- data/ext/polars/src/lazy/dsl.rs +59 -2
- data/ext/polars/src/lib.rs +151 -10
- data/ext/polars/src/series.rs +182 -29
- data/ext/polars/src/set.rs +91 -0
- data/ext/polars/src/utils.rs +19 -0
- data/lib/polars/batched_csv_reader.rb +1 -0
- data/lib/polars/cat_expr.rb +39 -0
- data/lib/polars/data_frame.rb +2284 -137
- data/lib/polars/date_time_expr.rb +1282 -7
- data/lib/polars/exceptions.rb +20 -0
- data/lib/polars/expr.rb +612 -7
- data/lib/polars/expr_dispatch.rb +14 -0
- data/lib/polars/functions.rb +219 -0
- data/lib/polars/group_by.rb +517 -0
- data/lib/polars/io.rb +421 -2
- data/lib/polars/lazy_frame.rb +1261 -67
- data/lib/polars/lazy_functions.rb +288 -10
- data/lib/polars/lazy_group_by.rb +79 -0
- data/lib/polars/list_expr.rb +5 -0
- data/lib/polars/meta_expr.rb +21 -0
- data/lib/polars/series.rb +1476 -212
- data/lib/polars/slice.rb +104 -0
- data/lib/polars/string_expr.rb +663 -2
- data/lib/polars/struct_expr.rb +73 -0
- data/lib/polars/utils.rb +43 -3
- data/lib/polars/version.rb +2 -1
- data/lib/polars/when.rb +1 -0
- data/lib/polars/when_then.rb +1 -0
- data/lib/polars.rb +7 -10
- metadata +9 -2
data/lib/polars/slice.rb
ADDED
@@ -0,0 +1,104 @@
|
|
1
|
+
module Polars
|
2
|
+
# @private
|
3
|
+
class Slice
|
4
|
+
def initialize(obj)
|
5
|
+
@obj = obj
|
6
|
+
end
|
7
|
+
|
8
|
+
# Apply a slice operation, taking advantage of any potential fast paths.
|
9
|
+
def apply(s)
|
10
|
+
# normalize slice
|
11
|
+
_slice_setup(s)
|
12
|
+
|
13
|
+
# check for fast-paths / single-operation calls
|
14
|
+
if @slice_length == 0
|
15
|
+
@obj.cleared
|
16
|
+
elsif @is_unbounded && [-1, 1].include?(@stride)
|
17
|
+
@stride < 0 ? @obj.reverse : @obj.clone
|
18
|
+
elsif @start >= 0 && @stop >= 0 && @stride == 1
|
19
|
+
@obj.slice(@start, @slice_length)
|
20
|
+
elsif @stride < 0 && @slice_length == 1
|
21
|
+
@obj.slice(@stop + 1, 1)
|
22
|
+
else
|
23
|
+
# multi-operation calls; make lazy
|
24
|
+
lazyobj = _lazify(@obj)
|
25
|
+
sliced = @stride > 0 ? _slice_positive(lazyobj) : _slice_negative(lazyobj)
|
26
|
+
_as_original(sliced, @obj)
|
27
|
+
end
|
28
|
+
end
|
29
|
+
|
30
|
+
private
|
31
|
+
|
32
|
+
# Return lazy variant back to its original type.
|
33
|
+
def _as_original(lazy, original)
|
34
|
+
frame = lazy.collect
|
35
|
+
original.is_a?(DataFrame) ? frame : frame.to_series
|
36
|
+
end
|
37
|
+
|
38
|
+
# Make lazy to ensure efficient/consistent handling.
|
39
|
+
def _lazify(obj)
|
40
|
+
obj.is_a?(DataFrame) ? obj.lazy : obj.to_frame.lazy
|
41
|
+
end
|
42
|
+
|
43
|
+
# Logic for slices with positive stride.
|
44
|
+
def _slice_positive(obj)
|
45
|
+
# note: at this point stride is guaranteed to be > 1
|
46
|
+
obj.slice(@start, @slice_length).take_every(@stride)
|
47
|
+
end
|
48
|
+
|
49
|
+
# Logic for slices with negative stride.
|
50
|
+
def _slice_negative(obj)
|
51
|
+
stride = @stride.abs
|
52
|
+
lazyslice = obj.slice(@stop + 1, @slice_length).reverse
|
53
|
+
stride > 1 ? lazyslice.take_every(stride) : lazyslice
|
54
|
+
end
|
55
|
+
|
56
|
+
# Normalize slice bounds, identify unbounded and/or zero-length slices.
|
57
|
+
def _slice_setup(s)
|
58
|
+
# can normalize slice indices as we know object size
|
59
|
+
obj_len = @obj.len
|
60
|
+
start = if s.begin
|
61
|
+
if s.begin < 0
|
62
|
+
[s.begin + obj_len, 0].max
|
63
|
+
else
|
64
|
+
s.begin
|
65
|
+
end
|
66
|
+
else
|
67
|
+
0
|
68
|
+
end
|
69
|
+
stop = if s.end
|
70
|
+
if s.end < 0
|
71
|
+
s.end + (s.exclude_end? ? 0 : 1) + obj_len
|
72
|
+
else
|
73
|
+
s.end + (s.exclude_end? ? 0 : 1)
|
74
|
+
end
|
75
|
+
else
|
76
|
+
obj_len
|
77
|
+
end
|
78
|
+
stride = 1
|
79
|
+
|
80
|
+
# check if slice is actually unbounded
|
81
|
+
if stride >= 1
|
82
|
+
@is_unbounded = start <= 0 && stop >= obj_len
|
83
|
+
else
|
84
|
+
@is_unbounded = stop == -1 && start >= obj_len - 1
|
85
|
+
end
|
86
|
+
|
87
|
+
# determine slice length
|
88
|
+
if @obj.is_empty
|
89
|
+
@slice_length = 0
|
90
|
+
elsif @is_unbounded
|
91
|
+
@slice_length = obj_len
|
92
|
+
else
|
93
|
+
@slice_length = if start == stop || (stride > 0 && start > stop) || (stride < 0 && start < stop)
|
94
|
+
0
|
95
|
+
else
|
96
|
+
(stop - start).abs
|
97
|
+
end
|
98
|
+
end
|
99
|
+
@start = start
|
100
|
+
@stop = stop
|
101
|
+
@stride = stride
|
102
|
+
end
|
103
|
+
end
|
104
|
+
end
|