Skip to main content

Series

Struct Series 

Source
pub struct Series { /* private fields */ }

Implementations§

Source§

impl Series

Source

pub fn new( name: impl Into<String>, index: Index, column: Column, ) -> Result<Self, FrameError>

Examples found in repository?
examples/bench_groupby_shift.rs (lines 28-32)
19fn main() {
20    let args: Vec<String> = std::env::args().collect();
21    let n: usize = args.get(1).and_then(|s| s.parse().ok()).unwrap_or(1_000_000);
22    let iters: usize = args.get(2).and_then(|s| s.parse().ok()).unwrap_or(30);
23    let groups = 100usize;
24
25    let labels: Vec<IndexLabel> = (0..n as i64).map(IndexLabel::Int64).collect();
26    let keys: Vec<i64> = (0..n).map(|i| (i % groups) as i64).collect();
27    let vals: Vec<f64> = (0..n).map(|i| (i.wrapping_mul(37) % 9973) as f64 * 0.25).collect();
28    let value = Series::new(
29        "v".to_string(),
30        Index::new(labels.clone()),
31        Column::from_f64_values(vals),
32    )
33    .unwrap();
34    let key = Series::new(
35        "k".to_string(),
36        Index::new(labels),
37        Column::from_i64_values(keys),
38    )
39    .unwrap();
40
41    let out = value.groupby(&key).unwrap().shift(1).unwrap();
42    let mut chk: u64 = 0xcbf29ce484222325;
43    for v in out.values() {
44        let bits = match v {
45            Scalar::Float64(f) => f.to_bits(),
46            _ => 0xDEAD_BEEF_DEAD_BEEF,
47        };
48        chk = (chk ^ bits).wrapping_mul(0x100000001b3);
49    }
50
51    let mut sink = 0usize;
52    let start = Instant::now();
53    for _ in 0..iters {
54        let s = black_box(value.groupby(&key).unwrap().shift(1).unwrap());
55        sink ^= s.len();
56    }
57    let elapsed = start.elapsed();
58    println!(
59        "groupby_shift n={n} iters={iters}: {:.3} ms/iter (chk={chk:016x} sink={sink})",
60        elapsed.as_secs_f64() * 1000.0 / iters as f64
61    );
62}
Source

pub fn from_values( name: impl Into<String>, index_labels: Vec<IndexLabel>, values: Vec<Scalar>, ) -> Result<Self, FrameError>

Examples found in repository?
examples/bench_iloc_gather.rs (line 18)
16fn s_i64(vals: Vec<i64>) -> Series {
17    let idx: Vec<IndexLabel> = (0..vals.len() as i64).map(IndexLabel::Int64).collect();
18    Series::from_values("s", idx, vals.into_iter().map(Scalar::Int64).collect()).unwrap()
19}
20
21fn s_scalars(vals: Vec<Scalar>) -> Series {
22    let idx: Vec<IndexLabel> = (0..vals.len() as i64).map(IndexLabel::Int64).collect();
23    Series::from_values("s", idx, vals).unwrap()
24}
More examples
Hide additional examples
examples/bench_sort_values_gather.rs (line 18)
16fn s_i64(vals: Vec<i64>) -> Series {
17    let idx: Vec<IndexLabel> = (0..vals.len() as i64).map(IndexLabel::Int64).collect();
18    Series::from_values("s", idx, vals.into_iter().map(Scalar::Int64).collect()).unwrap()
19}
20
21fn s_scalars(vals: Vec<Scalar>) -> Series {
22    let idx: Vec<IndexLabel> = (0..vals.len() as i64).map(IndexLabel::Int64).collect();
23    Series::from_values("s", idx, vals).unwrap()
24}
examples/bench_take_gather.rs (line 19)
17fn s_i64(vals: Vec<i64>) -> Series {
18    let idx: Vec<IndexLabel> = (0..vals.len() as i64).map(IndexLabel::Int64).collect();
19    Series::from_values("s", idx, vals.into_iter().map(Scalar::Int64).collect()).unwrap()
20}
21
22fn s_scalars(vals: Vec<Scalar>) -> Series {
23    let idx: Vec<IndexLabel> = (0..vals.len() as i64).map(IndexLabel::Int64).collect();
24    Series::from_values("s", idx, vals).unwrap()
25}
examples/bench_searchsorted.rs (line 21)
18fn s_i64(vals: Vec<i64>) -> Series {
19    let idx: Vec<IndexLabel> = (0..vals.len() as i64).map(IndexLabel::Int64).collect();
20    let sc: Vec<Scalar> = vals.into_iter().map(Scalar::Int64).collect();
21    Series::from_values("s", idx, sc).unwrap()
22}
23
24fn s_scalars(vals: Vec<Scalar>) -> Series {
25    let idx: Vec<IndexLabel> = (0..vals.len() as i64).map(IndexLabel::Int64).collect();
26    Series::from_values("s", idx, vals).unwrap()
27}
examples/bench_kendall.rs (line 18)
15fn s_from(vals: &[f64]) -> Series {
16    let idx: Vec<IndexLabel> = (0..vals.len() as i64).map(IndexLabel::Int64).collect();
17    let sc: Vec<Scalar> = vals.iter().map(|&v| Scalar::Float64(v)).collect();
18    Series::from_values("s", idx, sc).unwrap()
19}
examples/bench_rolling_var.rs (line 27)
24fn s_from(vals: &[f64]) -> Series {
25    let idx: Vec<IndexLabel> = (0..vals.len() as i64).map(IndexLabel::Int64).collect();
26    let sc: Vec<Scalar> = vals.iter().map(|&v| Scalar::Float64(v)).collect();
27    Series::from_values("s", idx, sc).unwrap()
28}
Source

pub fn from_pairs( name: impl Into<String>, pairs: Vec<(IndexLabel, Scalar)>, ) -> Result<Self, FrameError>

Construct a Series from key-value pairs (dict-style).

Keys become the index labels, values become the column. Matches pd.Series({"a": 1, "b": 2}).

Source

pub fn from_dict( name: impl Into<String>, data: BTreeMap<IndexLabel, Scalar>, ) -> Result<Self, FrameError>

Construct a Series from a dict (BTreeMap) of label → value.

Matches pd.Series({"a": 1, "b": 2}).

Source

pub fn arange( name: impl Into<String>, start: f64, stop: f64, step: f64, ) -> Result<Self, FrameError>

Create a Series with evenly spaced values within a given interval.

Matches np.arange(start, stop, step).

Source

pub fn linspace( name: impl Into<String>, start: f64, stop: f64, num: usize, ) -> Result<Self, FrameError>

Create a Series with evenly spaced values over [start, stop].

Matches np.linspace(start, stop, num).

Source

pub fn logspace( name: impl Into<String>, start: f64, stop: f64, num: usize, ) -> Result<Self, FrameError>

Create a Series with evenly spaced values on a log scale.

Matches np.logspace(start, stop, num).

Source

pub fn geomspace( name: impl Into<String>, start: f64, stop: f64, num: usize, ) -> Result<Self, FrameError>

Create a Series with values evenly spaced on a log scale (geometric progression).

Matches np.geomspace(start, stop, num).

Source

pub fn zeros(name: impl Into<String>, n: usize) -> Result<Self, FrameError>

Create a Series filled with zeros (Float64 by default).

Matches np.zeros(n).

Source

pub fn zeros_dtype( name: impl Into<String>, n: usize, dtype: DType, ) -> Result<Self, FrameError>

Create a Series filled with zeros of specified dtype.

Matches np.zeros(n, dtype=dtype).

Source

pub fn ones(name: impl Into<String>, n: usize) -> Result<Self, FrameError>

Create a Series filled with ones (Float64 by default).

Matches np.ones(n).

Source

pub fn ones_dtype( name: impl Into<String>, n: usize, dtype: DType, ) -> Result<Self, FrameError>

Create a Series filled with ones of specified dtype.

Matches np.ones(n, dtype=dtype).

Source

pub fn full( name: impl Into<String>, n: usize, fill_value: Scalar, ) -> Result<Self, FrameError>

Create a Series filled with a constant value.

Matches np.full(n, fill_value).

Source

pub fn hanning(name: impl Into<String>, m: usize) -> Result<Self, FrameError>

Generate a Hann (Hanning) window Series.

Matches np.hanning(M).

Source

pub fn hamming(name: impl Into<String>, m: usize) -> Result<Self, FrameError>

Generate a Hamming window Series.

Matches np.hamming(M).

Source

pub fn blackman(name: impl Into<String>, m: usize) -> Result<Self, FrameError>

Generate a Blackman window Series.

Matches np.blackman(M).

Source

pub fn bartlett(name: impl Into<String>, m: usize) -> Result<Self, FrameError>

Generate a Bartlett (triangular) window Series.

Matches np.bartlett(M).

Source

pub fn plot(&self) -> Result<PlotSpec, FrameError>

Return a backend-neutral pandas-style plotting request.

Source

pub fn hist(&self) -> Result<HistogramSpec, FrameError>

Return a backend-neutral pandas-style histogram request.

Source

pub fn to_string_repr(&self) -> String

Pretty-print the Series as a string table.

Matches str(series) / series.to_string() in pandas.

Source

pub fn broadcast( name: impl Into<String>, value: Scalar, index_labels: Vec<IndexLabel>, ) -> Result<Self, FrameError>

Broadcast a single scalar value across the given index.

Matches pd.Series(5, index=[0, 1, 2]).

Source

pub fn name(&self) -> &str

Source

pub fn index(&self) -> &Index

Examples found in repository?
examples/bench_loc.rs (line 34)
22fn golden() -> String {
23    let mut out = String::new();
24    // Duplicate index label 10 at positions 0 and 2.
25    let s = s_from(vec![10, 20, 10, 30], vec![100, 200, 300, 400]);
26    // Selector order [10, 30, 20]; 10 returns both matches (asc position).
27    let r = s
28        .loc(&[
29            IndexLabel::Int64(10),
30            IndexLabel::Int64(30),
31            IndexLabel::Int64(20),
32        ])
33        .unwrap();
34    out.push_str(&format!("labels={:?}\n", r.index().labels()));
35    out.push_str(&format!("values={:?}\n", r.values()));
36    // Duplicate selector entries preserved.
37    let r2 = s
38        .loc(&[IndexLabel::Int64(20), IndexLabel::Int64(20)])
39        .unwrap();
40    out.push_str(&format!("dup_sel_values={:?}\n", r2.values()));
41    // Missing label fails closed.
42    let err = s.loc(&[IndexLabel::Int64(99)]);
43    out.push_str(&format!("missing_is_err={}\n", err.is_err()));
44    out
45}
More examples
Hide additional examples
examples/bench_corrwith.rs (line 54)
34fn golden() -> String {
35    // self has rows r0,r1,r2,r3 ; other has r1 (dup, first wins), r0, r3, rX.
36    let s = frame(
37        vec![lbl("r0"), lbl("r1"), lbl("r2"), lbl("r3")],
38        vec![
39            ("a", vec![1.0, 2.0, 3.0, 4.0]),
40            ("b", vec![2.0, 1.0, 5.0, 4.0]),
41            ("c", vec![9.0, 8.0, 7.0, 1.0]),
42        ],
43    );
44    let o = frame(
45        vec![lbl("r1"), lbl("r0"), lbl("r3"), lbl("r1"), lbl("rX")],
46        vec![
47            ("a", vec![5.0, 1.5, 4.0, -9.0, 0.0]),
48            ("b", vec![6.0, 2.5, 3.0, -9.0, 0.0]),
49            ("c", vec![1.0, 0.5, 8.0, -9.0, 0.0]),
50        ],
51    );
52    let r = s.corrwith_axis(&o, 1).unwrap();
53    let mut out = String::new();
54    out.push_str(&format!("labels={:?}\n", r.index().labels()));
55    // Round values to 9 decimals for a stable digest.
56    let vals: Vec<String> = r
57        .column()
58        .values()
59        .iter()
60        .map(|v| match v {
61            Scalar::Float64(f) if f.is_nan() => "nan".to_string(),
62            Scalar::Float64(f) => format!("{:.9}", f),
63            other => format!("{other:?}"),
64        })
65        .collect();
66    out.push_str(&format!("values={:?}\n", vals));
67    out
68}
examples/bench_iloc_gather.rs (line 31)
26fn golden() -> String {
27    let mut out = String::new();
28    let s = s_i64(vec![10, 20, 30, 40, 50]);
29    // reorder + negative indices + duplicates
30    let r = s.iloc(&[4, 0, -1, 2, -5, 2]).unwrap();
31    out.push_str(&format!("i64_lbls={:?}\n", r.index().labels()));
32    out.push_str(&format!("i64_vals={:?}\n", r.values()));
33
34    // Float64 incl NaN
35    let f = s_scalars(vec![
36        Scalar::Float64(1.5),
37        Scalar::Float64(f64::NAN),
38        Scalar::Float64(-3.0),
39    ]);
40    out.push_str(&format!("f64={:?}\n", f.iloc(&[2, 1, 0]).unwrap().values()));
41
42    // Nullable Int64 (Null present => not all-valid path)
43    let ni = s_scalars(vec![
44        Scalar::Int64(7),
45        Scalar::Null(NullKind::NaN),
46        Scalar::Int64(9),
47    ]);
48    out.push_str(&format!("ni={:?}\n", ni.iloc(&[1, 2, 0]).unwrap().values()));
49
50    // Utf8 + Bool
51    let u = s_scalars(
52        vec!["a", "b", "c"]
53            .into_iter()
54            .map(|x| Scalar::Utf8(x.into()))
55            .collect(),
56    );
57    out.push_str(&format!("utf8={:?}\n", u.iloc(&[2, -3]).unwrap().values()));
58    let b = s_scalars(vec![Scalar::Bool(true), Scalar::Bool(false)]);
59    out.push_str(&format!(
60        "bool={:?}\n",
61        b.iloc(&[1, 0, 1]).unwrap().values()
62    ));
63
64    // Out-of-bounds errors
65    out.push_str(&format!("oob_err={}\n", s.iloc(&[99]).is_err()));
66    out
67}
examples/bench_sort_index.rs (line 37)
32fn golden() -> String {
33    let mut out = String::new();
34    // Duplicate labels 1 and 3 with distinct values prove stable tie order.
35    let s = series(vec![3, 1, 2, 1, 3], vec![10, 20, 30, 40, 50]);
36    let asc = s.sort_index(true).unwrap();
37    out.push_str(&format!("s_asc_labels={:?}\n", asc.index().labels()));
38    out.push_str(&format!("s_asc_vals={:?}\n", asc.values()));
39    let desc = s.sort_index(false).unwrap();
40    out.push_str(&format!("s_desc_labels={:?}\n", desc.index().labels()));
41    out.push_str(&format!("s_desc_vals={:?}\n", desc.values()));
42
43    // Negative + zero labels.
44    let s2 = series(vec![0, -5, 7, -5, 0], vec![1, 2, 3, 4, 5]);
45    let a2 = s2.sort_index(true).unwrap();
46    out.push_str(&format!("s2_asc_labels={:?}\n", a2.index().labels()));
47    out.push_str(&format!("s2_asc_vals={:?}\n", a2.values()));
48
49    let df = frame(vec![3, 1, 2, 1, 3], vec![10, 20, 30, 40, 50]);
50    let dfa = df.sort_index(true).unwrap();
51    out.push_str(&format!("df_asc_labels={:?}\n", dfa.index().labels()));
52    out.push_str(&format!(
53        "df_asc_v={:?}\n",
54        dfa.columns().get("v").unwrap().values()
55    ));
56    let dfd = df.sort_index(false).unwrap();
57    out.push_str(&format!("df_desc_labels={:?}\n", dfd.index().labels()));
58    out.push_str(&format!(
59        "df_desc_v={:?}\n",
60        dfd.columns().get("v").unwrap().values()
61    ));
62    out
63}
examples/bench_take_gather.rs (line 33)
27fn golden() -> String {
28    let mut out = String::new();
29
30    // Series::take across dtypes, negative + duplicate indices.
31    let s = s_i64(vec![10, 20, 30, 40, 50]);
32    let r = s.take(&[4, 0, -1, 2, -5, 2]).unwrap();
33    out.push_str(&format!("take_lbls={:?}\n", r.index().labels()));
34    out.push_str(&format!("take_vals={:?}\n", r.values()));
35    out.push_str(&format!("take_oob_err={}\n", s.take(&[99]).is_err()));
36
37    let f = s_scalars(vec![
38        Scalar::Float64(1.5),
39        Scalar::Float64(f64::NAN),
40        Scalar::Float64(-3.0),
41    ]);
42    out.push_str(&format!(
43        "take_f64={:?}\n",
44        f.take(&[2, 1, 0]).unwrap().values()
45    ));
46    let ni = s_scalars(vec![
47        Scalar::Int64(7),
48        Scalar::Null(NullKind::NaN),
49        Scalar::Int64(9),
50    ]);
51    out.push_str(&format!(
52        "take_ni={:?}\n",
53        ni.take(&[1, 2, 0]).unwrap().values()
54    ));
55    let u = s_scalars(
56        vec!["a", "b", "c"]
57            .into_iter()
58            .map(|x| Scalar::Utf8(x.into()))
59            .collect(),
60    );
61    out.push_str(&format!(
62        "take_utf8={:?}\n",
63        u.take(&[2, -3]).unwrap().values()
64    ));
65
66    // SeriesGroupBy gather paths (nlargest / head) route through take_positions.
67    let data = s_i64(vec![5, 1, 9, 3, 7, 2, 8]);
68    let keys = s_scalars(
69        vec!["a", "b", "a", "b", "a", "b", "a"]
70            .into_iter()
71            .map(|x| Scalar::Utf8(x.into()))
72            .collect(),
73    );
74    let gb = data.groupby(&keys).unwrap();
75    let nl = gb.nlargest(2).unwrap();
76    out.push_str(&format!("gb_nlargest_lbls={:?}\n", nl.index().labels()));
77    out.push_str(&format!("gb_nlargest_vals={:?}\n", nl.values()));
78    let hd = data.groupby(&keys).unwrap().head(1).unwrap();
79    out.push_str(&format!("gb_head_vals={:?}\n", hd.values()));
80    out
81}
Source

pub fn column(&self) -> &Column

Examples found in repository?
examples/bench_corrwith.rs (line 57)
34fn golden() -> String {
35    // self has rows r0,r1,r2,r3 ; other has r1 (dup, first wins), r0, r3, rX.
36    let s = frame(
37        vec![lbl("r0"), lbl("r1"), lbl("r2"), lbl("r3")],
38        vec![
39            ("a", vec![1.0, 2.0, 3.0, 4.0]),
40            ("b", vec![2.0, 1.0, 5.0, 4.0]),
41            ("c", vec![9.0, 8.0, 7.0, 1.0]),
42        ],
43    );
44    let o = frame(
45        vec![lbl("r1"), lbl("r0"), lbl("r3"), lbl("r1"), lbl("rX")],
46        vec![
47            ("a", vec![5.0, 1.5, 4.0, -9.0, 0.0]),
48            ("b", vec![6.0, 2.5, 3.0, -9.0, 0.0]),
49            ("c", vec![1.0, 0.5, 8.0, -9.0, 0.0]),
50        ],
51    );
52    let r = s.corrwith_axis(&o, 1).unwrap();
53    let mut out = String::new();
54    out.push_str(&format!("labels={:?}\n", r.index().labels()));
55    // Round values to 9 decimals for a stable digest.
56    let vals: Vec<String> = r
57        .column()
58        .values()
59        .iter()
60        .map(|v| match v {
61            Scalar::Float64(f) if f.is_nan() => "nan".to_string(),
62            Scalar::Float64(f) => format!("{:.9}", f),
63            other => format!("{other:?}"),
64        })
65        .collect();
66    out.push_str(&format!("values={:?}\n", vals));
67    out
68}
Source

pub fn values(&self) -> &[Scalar]

Examples found in repository?
examples/bench_rolling_var.rs (line 131)
129fn fmt_series(s: &Series) -> String {
130    let mut out = String::new();
131    for v in s.values() {
132        match v {
133            Scalar::Float64(f) => {
134                if f.is_nan() {
135                    out.push_str("nan ");
136                } else {
137                    out.push_str(&format!("{:016x} ", f.to_bits()));
138                }
139            }
140            Scalar::Null(_) => out.push_str("null "),
141            other => out.push_str(&format!("?{other:?} ")),
142        }
143    }
144    out
145}
146
147fn golden() -> String {
148    let mut out = String::new();
149    let data: &[&[f64]] = &[
150        &[1.0, 2.0, 3.0, 4.0, 5.0, 6.0, 7.0, 8.0],
151        &[3.5, -1.0, 2.25, 0.0, 9.9, -4.4, 8.1, 2.2, 7.7, -3.3],
152        &[1e8, 1.0, 1e-8, -1e8, 42.0],
153    ];
154    for (di, d) in data.iter().enumerate() {
155        let s = s_from(d);
156        for &window in &[2usize, 3, 5] {
157            for &mp in &[None, Some(1usize), Some(window)] {
158                for &center in &[false, true] {
159                    for a in ALL_AGGS {
160                        let res = run_api(&s, window, mp, center, a);
161                        out.push_str(&format!(
162                            "d{di} w{window} mp{mp:?} c{center} {}: {}\n",
163                            agg_name(a),
164                            fmt_series(&res)
165                        ));
166                    }
167                }
168            }
169        }
170    }
171    out
172}
173
174fn cross_check() -> (usize, usize) {
175    let mut state: u64 = 0x9E3779B97F4A7C15;
176    let mut next = || {
177        state = state
178            .wrapping_mul(6364136223846793005)
179            .wrapping_add(1442695040888963407);
180        state
181    };
182    let (mut ok, mut bad) = (0usize, 0usize);
183    for _ in 0..3000 {
184        let n = (next() % 60) as usize + 1;
185        let xs: Vec<f64> = (0..n)
186            .map(|_| (next() % 20000) as f64 / 100.0 - 100.0)
187            .collect();
188        let window = (next() % 8) as usize + 1;
189        let mp_pick = next() % 3;
190        let mp = match mp_pick {
191            0 => None,
192            1 => Some(1usize),
193            _ => Some(window),
194        };
195        let center = next() % 2 == 0;
196        let a = if next() % 2 == 0 { Agg::Var } else { Agg::Std };
197        let s = s_from(&xs);
198        let got = run_api(&s, window, mp, center, a);
199        let mp_eff = mp.unwrap_or(window);
200        let want = ref_values(&xs, window, mp_eff, center, a);
201        let got_vals = got.values();
202        let mut row_ok = got_vals.len() == want.len();
203        if row_ok {
204            for (g, w) in got_vals.iter().zip(want.iter()) {
205                let matches = match g {
206                    Scalar::Null(_) => w.is_nan() && mp_eff > 0, // min_periods-null sentinel
207                    Scalar::Float64(f) => {
208                        f.to_bits() == w.to_bits() || (f.is_nan() && w.is_nan())
209                    }
210                    _ => false,
211                };
212                if !matches {
213                    row_ok = false;
214                    break;
215                }
216            }
217        }
218        if row_ok {
219            ok += 1;
220        } else {
221            bad += 1;
222            if bad <= 3 {
223                eprintln!("MISMATCH n={n} w={window} mp={mp:?} c={center} agg={}", agg_name(a));
224            }
225        }
226    }
227    (ok, bad)
228}
229
230/// FNV-1a 64-bit over the full golden battery — a stable parity fingerprint
231/// that survives rch's tail-truncated output (the verbose per-row dump can
232/// scroll off; this single line cannot).
233fn fnv1a64(s: &str) -> u64 {
234    let mut h: u64 = 0xcbf29ce484222325;
235    for b in s.as_bytes() {
236        h ^= *b as u64;
237        h = h.wrapping_mul(0x100000001b3);
238    }
239    h
240}
241
242fn main() {
243    let g = golden();
244    println!("GOLDEN_FNV1A64 {:016x} len={}", fnv1a64(&g), g.len());
245
246    let (ok, bad) = cross_check();
247    println!("CROSSCHECK ok={ok} bad={bad}");
248
249    // Large all-valid Float64 series; moderate window so the per-window
250    // two-pass var/std dominates. Deterministic data.
251    let n: usize = 200_000;
252    let window: usize = 250;
253    let xs: Vec<f64> = (0..n)
254        .map(|i| ((i as f64) * 0.31).sin() * 100.0 + ((i % 997) as f64))
255        .collect();
256    let s = s_from(&xs);
257
258    for a in [Agg::Var, Agg::Std, Agg::Skew, Agg::Sem] {
259        let t = Instant::now();
260        let res = run_api(&s, window, None, false, a);
261        let d = t.elapsed();
262        // touch output so it is not optimized away
263        let last = res.values().last().cloned();
264        println!(
265            "TIMING n={n} window={window} {}={:.3}ms last={:?}",
266            agg_name(a),
267            d.as_secs_f64() * 1e3,
268            last
269        );
270    }
271}
More examples
Hide additional examples
examples/bench_translate.rs (line 31)
25fn golden() -> String {
26    let mut out = String::new();
27    let s = s_from(vec!["hello world", "abcXYZ", "", "duplicate-d"]);
28
29    // basic 1:1 replacement
30    let r = s.str().translate("lo", "LO").unwrap();
31    out.push_str(&format!("basic={:?}\n", r.values()));
32
33    // `to` shorter than `from` => extra source chars are DELETED. 'o'->'0',
34    // but 'l' (index 1) has no target so every 'l' is removed.
35    let r2 = s.str().translate("ol", "0").unwrap();
36    out.push_str(&format!("delete={:?}\n", r2.values()));
37
38    // duplicate source char in `from`: first occurrence wins ('d'->'1', not '2')
39    let r3 = s.str().translate("dd", "12").unwrap();
40    out.push_str(&format!("dupsrc={:?}\n", r3.values()));
41
42    // empty table: identity
43    let r4 = s.str().translate("", "").unwrap();
44    out.push_str(&format!("empty={:?}\n", r4.values()));
45    out
46}
examples/bench_loc.rs (line 35)
22fn golden() -> String {
23    let mut out = String::new();
24    // Duplicate index label 10 at positions 0 and 2.
25    let s = s_from(vec![10, 20, 10, 30], vec![100, 200, 300, 400]);
26    // Selector order [10, 30, 20]; 10 returns both matches (asc position).
27    let r = s
28        .loc(&[
29            IndexLabel::Int64(10),
30            IndexLabel::Int64(30),
31            IndexLabel::Int64(20),
32        ])
33        .unwrap();
34    out.push_str(&format!("labels={:?}\n", r.index().labels()));
35    out.push_str(&format!("values={:?}\n", r.values()));
36    // Duplicate selector entries preserved.
37    let r2 = s
38        .loc(&[IndexLabel::Int64(20), IndexLabel::Int64(20)])
39        .unwrap();
40    out.push_str(&format!("dup_sel_values={:?}\n", r2.values()));
41    // Missing label fails closed.
42    let err = s.loc(&[IndexLabel::Int64(99)]);
43    out.push_str(&format!("missing_is_err={}\n", err.is_err()));
44    out
45}
examples/bench_contains_any.rs (line 30)
25fn golden() -> String {
26    let mut out = String::new();
27    let s = s_from(vec!["hello world", "foobar", "BAZ qux", "", "a.b+c"]);
28
29    let r = s.str().contains_any(&["world", "qux"]).unwrap();
30    out.push_str(&format!("hit={:?}\n", r.values()));
31
32    // Regex metacharacters must be treated as LITERALS.
33    let r2 = s.str().contains_any(&["a.b+c", "zz"]).unwrap();
34    out.push_str(&format!("literal_meta={:?}\n", r2.values()));
35
36    // Case sensitive (no match for lowercase 'baz').
37    let r3 = s.str().contains_any(&["baz"]).unwrap();
38    out.push_str(&format!("case={:?}\n", r3.values()));
39
40    // Empty pattern set => all false.
41    let r4 = s.str().contains_any(&[]).unwrap();
42    out.push_str(&format!("empty={:?}\n", r4.values()));
43
44    // Empty-string pattern matches every (non-null) string.
45    let r5 = s.str().contains_any(&["", "zz"]).unwrap();
46    out.push_str(&format!("empty_pat={:?}\n", r5.values()));
47    out
48}
examples/bench_startswith_any.rs (line 30)
25fn golden() -> String {
26    let mut out = String::new();
27    let s = s_from(vec!["https://a.com", "ftp://x", "file.txt", "", "a.b+c"]);
28
29    let r = s.str().startswith_any(&["https://", "ftp://"]).unwrap();
30    out.push_str(&format!("sw_hit={:?}\n", r.values()));
31    // metacharacters stay literal
32    let r2 = s.str().startswith_any(&["a.b+c"]).unwrap();
33    out.push_str(&format!("sw_meta={:?}\n", r2.values()));
34    let r3 = s.str().endswith_any(&[".txt", ".com"]).unwrap();
35    out.push_str(&format!("ew_hit={:?}\n", r3.values()));
36    // empty pattern set => all false
37    let r4 = s.str().startswith_any(&[]).unwrap();
38    out.push_str(&format!("empty={:?}\n", r4.values()));
39    // empty-string pattern matches every non-null string
40    let r5 = s.str().endswith_any(&["", "zz"]).unwrap();
41    out.push_str(&format!("empty_pat={:?}\n", r5.values()));
42
43    // with_na variants (null fill).
44    let sn = Series::from_values(
45        "s",
46        vec![IndexLabel::Int64(0), IndexLabel::Int64(1)],
47        vec![
48            Scalar::Utf8("https://z".into()),
49            Scalar::Null(fp_types::NullKind::NaN),
50        ],
51    )
52    .unwrap();
53    let rn = sn
54        .str()
55        .startswith_any_with_na(&["https://"], Some(true))
56        .unwrap();
57    out.push_str(&format!("na_fill={:?}\n", rn.values()));
58    out
59}
examples/bench_iloc_gather.rs (line 32)
26fn golden() -> String {
27    let mut out = String::new();
28    let s = s_i64(vec![10, 20, 30, 40, 50]);
29    // reorder + negative indices + duplicates
30    let r = s.iloc(&[4, 0, -1, 2, -5, 2]).unwrap();
31    out.push_str(&format!("i64_lbls={:?}\n", r.index().labels()));
32    out.push_str(&format!("i64_vals={:?}\n", r.values()));
33
34    // Float64 incl NaN
35    let f = s_scalars(vec![
36        Scalar::Float64(1.5),
37        Scalar::Float64(f64::NAN),
38        Scalar::Float64(-3.0),
39    ]);
40    out.push_str(&format!("f64={:?}\n", f.iloc(&[2, 1, 0]).unwrap().values()));
41
42    // Nullable Int64 (Null present => not all-valid path)
43    let ni = s_scalars(vec![
44        Scalar::Int64(7),
45        Scalar::Null(NullKind::NaN),
46        Scalar::Int64(9),
47    ]);
48    out.push_str(&format!("ni={:?}\n", ni.iloc(&[1, 2, 0]).unwrap().values()));
49
50    // Utf8 + Bool
51    let u = s_scalars(
52        vec!["a", "b", "c"]
53            .into_iter()
54            .map(|x| Scalar::Utf8(x.into()))
55            .collect(),
56    );
57    out.push_str(&format!("utf8={:?}\n", u.iloc(&[2, -3]).unwrap().values()));
58    let b = s_scalars(vec![Scalar::Bool(true), Scalar::Bool(false)]);
59    out.push_str(&format!(
60        "bool={:?}\n",
61        b.iloc(&[1, 0, 1]).unwrap().values()
62    ));
63
64    // Out-of-bounds errors
65    out.push_str(&format!("oob_err={}\n", s.iloc(&[99]).is_err()));
66    out
67}
Source

pub fn array(&self) -> Vec<Scalar>

Object-array-shaped materialization of the Series values.

Matches pd.Series.array at the API-shape level for the current immutable scalar-vector representation.

Source

pub fn ravel(&self) -> Vec<Scalar>

Flatten Series values to a one-dimensional scalar vector.

Matches pd.Series.ravel() for this already-1D representation.

Source

pub fn tolist(&self) -> Vec<Scalar>

Pandas spelling alias for Self::to_list.

Matches pd.Series.tolist().

Source

pub fn view(&self) -> Self

Return a shallow clone view.

Matches pd.Series.view() for this immutable Rust representation.

Source

pub fn transpose(&self) -> Self

Series transpose is identity.

Matches pd.Series.transpose().

Source

pub fn t(&self) -> Self

Lowercase alias for Self::transpose.

Source

pub fn T(&self) -> Self

Uppercase pandas spelling for Self::transpose.

Rust style prefers Self::t, but pandas exposes series.T.

Source

pub fn swapaxes(&self) -> Self

Swap Series axes.

Matches pd.Series.swapaxes() for a one-dimensional object; the operation is identity because Series has only axis 0.

Source

pub fn swaplevel(&self) -> Self

Swap the last two tuple-style index levels.

Matches pd.Series.swaplevel() for the tuple-label MultiIndex representation currently used by FrankenPandas. Non-tuple labels are returned unchanged, matching the existing DataFrame fallback shape.

Source

pub fn reorder_levels(&self, order: &[usize]) -> Result<Self, FrameError>

Reorder tuple-style index levels.

Matches pd.Series.reorder_levels(order) for labels formatted like (level0, level1, ...). Single-level Series accept [0] as identity.

Source

pub fn dtype(&self) -> DType

Return the dtype of this Series.

Matches pd.Series.dtype.

Source

pub fn dtypes(&self) -> DType

Plural pandas alias for Self::dtype.

Matches pd.Series.dtypes.

Source

pub fn copy(&self) -> Self

Return a deep copy of this Series.

Matches pd.Series.copy(deep=True).

Source

pub fn keys(&self) -> Index

Return the Series index.

Matches pd.Series.keys(). This is an alias for the index.

Source

pub fn add_with_policy( &self, other: &Self, policy: &RuntimePolicy, ledger: &mut EvidenceLedger, ) -> Result<Self, FrameError>

Source

pub fn add(&self, other: &Self) -> Result<Self, FrameError>

Source

pub fn sub_with_policy( &self, other: &Self, policy: &RuntimePolicy, ledger: &mut EvidenceLedger, ) -> Result<Self, FrameError>

Source

pub fn sub(&self, other: &Self) -> Result<Self, FrameError>

Source

pub fn mul_with_policy( &self, other: &Self, policy: &RuntimePolicy, ledger: &mut EvidenceLedger, ) -> Result<Self, FrameError>

Source

pub fn mul(&self, other: &Self) -> Result<Self, FrameError>

Source

pub fn div_with_policy( &self, other: &Self, policy: &RuntimePolicy, ledger: &mut EvidenceLedger, ) -> Result<Self, FrameError>

Source

pub fn div(&self, other: &Self) -> Result<Self, FrameError>

Source

pub fn add_fill( &self, other: &Self, fill_value: f64, ) -> Result<Self, FrameError>

Add with fill_value for NaN handling.

Matches s1.add(s2, fill_value=0).

Source

pub fn sub_fill( &self, other: &Self, fill_value: f64, ) -> Result<Self, FrameError>

Subtract with fill_value for NaN handling.

Source

pub fn mul_fill( &self, other: &Self, fill_value: f64, ) -> Result<Self, FrameError>

Multiply with fill_value for NaN handling.

Source

pub fn div_fill( &self, other: &Self, fill_value: f64, ) -> Result<Self, FrameError>

Divide with fill_value for NaN handling.

Source

pub fn modulo(&self, other: &Self) -> Result<Self, FrameError>

Modulo operation (element-wise remainder).

Matches s1.mod(s2) / s1 % s2 in pandas.

Source

pub fn modulo_with_policy( &self, other: &Self, policy: &RuntimePolicy, ledger: &mut EvidenceLedger, ) -> Result<Self, FrameError>

Source

pub fn floordiv(&self, other: &Self) -> Result<Self, FrameError>

Floor-division operation (element-wise).

Matches s1.floordiv(s2) / s1 // s2 in pandas.

Source

pub fn floordiv_with_policy( &self, other: &Self, policy: &RuntimePolicy, ledger: &mut EvidenceLedger, ) -> Result<Self, FrameError>

Source

pub fn pow(&self, other: &Self) -> Result<Self, FrameError>

Power operation (element-wise exponentiation).

Matches s1.pow(s2) / s1 ** s2 in pandas.

Source

pub fn pow_with_policy( &self, other: &Self, policy: &RuntimePolicy, ledger: &mut EvidenceLedger, ) -> Result<Self, FrameError>

Source

pub fn subtract(&self, other: &Self) -> Result<Self, FrameError>

pandas alias for Self::sub. Matches pd.Series.subtract.

Source

pub fn multiply(&self, other: &Self) -> Result<Self, FrameError>

pandas alias for Self::mul. Matches pd.Series.multiply.

Source

pub fn divide(&self, other: &Self) -> Result<Self, FrameError>

pandas alias for Self::div. Matches pd.Series.divide.

Source

pub fn truediv(&self, other: &Self) -> Result<Self, FrameError>

pandas alias for Self::div. Matches pd.Series.truediv (true / floating-point division; same as div since div itself promotes to Float64).

Source

pub fn mod(&self, other: &Self) -> Result<Self, FrameError>

Element-wise modulo. Matches pd.Series.mod(other) / s1 % s2.

mod is a Rust keyword; the public name uses the raw-identifier form. Callers from Rust write series.r#mod(&other). The Python FFI surface exposes it as bare mod.

Source

pub fn radd(&self, other: &Self) -> Result<Self, FrameError>

Right-handed addition: s1.radd(s2)s2.add(s1). Useful for reverse operator overloading (scalar + series). Matches pd.Series.radd(other).

Source

pub fn rsub(&self, other: &Self) -> Result<Self, FrameError>

Right-handed subtraction: s1.rsub(s2)s2.sub(s1). Matches pd.Series.rsub(other).

Source

pub fn rmul(&self, other: &Self) -> Result<Self, FrameError>

Right-handed multiplication: s1.rmul(s2)s2.mul(s1). Matches pd.Series.rmul(other).

Source

pub fn rdiv(&self, other: &Self) -> Result<Self, FrameError>

Right-handed division: s1.rdiv(s2)s2.div(s1). Matches pd.Series.rdiv(other).

Source

pub fn rtruediv(&self, other: &Self) -> Result<Self, FrameError>

Right-handed true division: s1.rtruediv(s2)s2.div(s1). Matches pd.Series.rtruediv(other).

Source

pub fn rfloordiv(&self, other: &Self) -> Result<Self, FrameError>

Right-handed floor division: s1.rfloordiv(s2)s2.floordiv(s1). Matches pd.Series.rfloordiv(other).

Source

pub fn rmod(&self, other: &Self) -> Result<Self, FrameError>

Right-handed modulo: s1.rmod(s2)s2.modulo(s1). Matches pd.Series.rmod(other).

Source

pub fn rpow(&self, other: &Self) -> Result<Self, FrameError>

Right-handed exponentiation: s1.rpow(s2)s2.pow(s1). Matches pd.Series.rpow(other).

Source

pub fn divmod(&self, other: &Self) -> Result<(Self, Self), FrameError>

Element-wise divmod: returns (self // other, self % other).

Matches pd.Series.divmod(other). The two returned Series share the aligned union index produced by floordiv/modulo; alignment and null-propagation semantics follow the same rules as those operators.

Source

pub fn rdivmod(&self, other: &Self) -> Result<(Self, Self), FrameError>

Reversed element-wise divmod: returns (other // self, other % self).

Matches pd.Series.rdivmod(other).

Source

pub fn td_add(&self, other: &Self) -> Result<Self, FrameError>

Add two Timedelta64 Series element-wise.

Matches td1 + td2 in pandas for timedelta Series.

Source

pub fn td_sub(&self, other: &Self) -> Result<Self, FrameError>

Subtract Timedelta64 Series element-wise.

Matches td1 - td2 in pandas for timedelta Series.

Source

pub fn td_mul_scalar(&self, scalar: f64) -> Result<Self, FrameError>

Multiply Timedelta64 Series by a numeric scalar.

Matches td * scalar in pandas.

Source

pub fn td_div_scalar(&self, scalar: f64) -> Result<Self, FrameError>

Divide Timedelta64 Series by a numeric scalar.

Matches td / scalar in pandas.

Source

pub fn td_floordiv_scalar(&self, scalar: i64) -> Result<Self, FrameError>

Floor-divide Timedelta64 Series by a numeric scalar.

Matches td // scalar in pandas.

Source

pub fn td_ratio(&self, other: &Self) -> Result<Self, FrameError>

Divide Timedelta64 by Timedelta64 to get a numeric ratio.

Matches td1 / td2 in pandas (returns float).

Source

pub fn td_mod(&self, other: &Self) -> Result<Self, FrameError>

Modulo of Timedelta64 Series by another Timedelta64.

Matches td1 % td2 in pandas.

Source

pub fn td_neg(&self) -> Result<Self, FrameError>

Negate Timedelta64 Series (unary minus).

Matches -td in pandas.

Source

pub fn td_abs(&self) -> Result<Self, FrameError>

Absolute value of Timedelta64 Series.

Matches td.abs() or abs(td) in pandas.

Source

pub fn td_lt(&self, other: &Self) -> Result<Self, FrameError>

Compare Timedelta64 Series: less than.

Source

pub fn td_le(&self, other: &Self) -> Result<Self, FrameError>

Compare Timedelta64 Series: less than or equal.

Source

pub fn td_gt(&self, other: &Self) -> Result<Self, FrameError>

Compare Timedelta64 Series: greater than.

Source

pub fn td_ge(&self, other: &Self) -> Result<Self, FrameError>

Compare Timedelta64 Series: greater than or equal.

Source

pub fn td_eq(&self, other: &Self) -> Result<Self, FrameError>

Compare Timedelta64 Series: equality.

Source

pub fn td_ne(&self, other: &Self) -> Result<Self, FrameError>

Compare Timedelta64 Series: inequality.

Source

pub fn len(&self) -> usize

Return the number of elements in this Series.

Examples found in repository?
examples/bench_loc.rs (line 60)
47fn main() {
48    let g = golden();
49    print!("GOLDEN_BEGIN\n{g}GOLDEN_END\n");
50
51    let n: usize = 60_000;
52    let labels: Vec<i64> = (0..n as i64).collect();
53    let vals: Vec<i64> = (0..n as i64).map(|v| v * 2).collect();
54    let s = s_from(labels.clone(), vals);
55    let selector: Vec<IndexLabel> = (0..n as i64).map(IndexLabel::Int64).collect();
56
57    let t = Instant::now();
58    let r = s.loc(&selector).unwrap();
59    let d = t.elapsed();
60    assert_eq!(r.len(), n);
61
62    println!("TIMING n={n} m={n} loc={:.3}ms", d.as_secs_f64() * 1e3);
63}
More examples
Hide additional examples
examples/bench_sort_values_gather.rs (line 113)
92fn main() {
93    let g = golden();
94    print!("GOLDEN_BEGIN\n{g}GOLDEN_END\n");
95
96    let n: usize = 1_000_000;
97    let mut x: u64 = 0x9e37_79b9;
98    let vals: Vec<i64> = (0..n)
99        .map(|_| {
100            x = x
101                .wrapping_mul(6364136223846793005)
102                .wrapping_add(1442695040888963407);
103            (x >> 16) as i64 % 1_000_000
104        })
105        .collect();
106    let s = s_i64(vals);
107
108    let _ = s.sort_values(true).unwrap(); // warmup
109
110    let t = Instant::now();
111    let r = s.sort_values(true).unwrap();
112    let d = t.elapsed();
113    assert_eq!(r.len(), n);
114
115    println!("TIMING n={n} sort_values={:.3}ms", d.as_secs_f64() * 1e3);
116}
examples/bench_take_gather.rs (line 104)
83fn main() {
84    let g = golden();
85    print!("GOLDEN_BEGIN\n{g}GOLDEN_END\n");
86
87    let n: usize = 1_000_000;
88    let s = s_i64((0..n as i64).map(|v| v * 2).collect());
89    let mut x: u64 = 0xfeed_face;
90    let idxs: Vec<i64> = (0..n)
91        .map(|_| {
92            x = x
93                .wrapping_mul(6364136223846793005)
94                .wrapping_add(1442695040888963407);
95            (x >> 16) as i64 % (n as i64)
96        })
97        .collect();
98
99    let _ = s.take(&idxs).unwrap(); // warmup
100
101    let t = Instant::now();
102    let r = s.take(&idxs).unwrap();
103    let d = t.elapsed();
104    assert_eq!(r.len(), n);
105
106    println!("TIMING n={n} take={:.3}ms", d.as_secs_f64() * 1e3);
107}
examples/bench_iloc_gather.rs (line 91)
69fn main() {
70    let g = golden();
71    print!("GOLDEN_BEGIN\n{g}GOLDEN_END\n");
72
73    let n: usize = 1_000_000;
74    let s = s_i64((0..n as i64).map(|v| v * 2).collect());
75    // Shuffled full permutation (LCG).
76    let mut x: u64 = 0xdead_beef;
77    let mut pos: Vec<i64> = (0..n as i64).collect();
78    for i in (1..n).rev() {
79        x = x
80            .wrapping_mul(6364136223846793005)
81            .wrapping_add(1442695040888963407);
82        let j = (x >> 16) as usize % (i + 1);
83        pos.swap(i, j);
84    }
85
86    let _ = s.iloc(&pos).unwrap(); // warmup
87
88    let t = Instant::now();
89    let r = s.iloc(&pos).unwrap();
90    let d = t.elapsed();
91    assert_eq!(r.len(), n);
92
93    println!("TIMING n={n} iloc={:.3}ms", d.as_secs_f64() * 1e3);
94}
examples/bench_sort_index.rs (line 89)
65fn main() {
66    let g = golden();
67    print!("GOLDEN_BEGIN\n{g}GOLDEN_END\n");
68
69    let n: usize = 200_000;
70    // Shuffled (LCG) i64 index so it is unsorted and Int64-typed.
71    let mut x: u64 = 0x1234_5678;
72    let labels: Vec<i64> = (0..n)
73        .map(|_| {
74            x = x
75                .wrapping_mul(6364136223846793005)
76                .wrapping_add(1442695040888963407);
77            (x >> 16) as i64 % (n as i64)
78        })
79        .collect();
80    let vals: Vec<i64> = (0..n as i64).collect();
81    let s = series(labels, vals);
82
83    // warmup
84    let _ = s.sort_index(true).unwrap();
85
86    let t = Instant::now();
87    let r = s.sort_index(true).unwrap();
88    let d = t.elapsed();
89    assert_eq!(r.len(), n);
90
91    println!("TIMING n={n} sort_index={:.3}ms", d.as_secs_f64() * 1e3);
92}
examples/bench_startswith_any.rs (line 79)
61fn main() {
62    let g = golden();
63    print!("GOLDEN_BEGIN\n{g}GOLDEN_END\n");
64
65    // Worst case: many prefixes sharing a long common stem.
66    let pats_owned: Vec<String> = (0..200)
67        .map(|i| format!("https://cdn.example.com/path/{i:04}/"))
68        .collect();
69    let pats: Vec<&str> = pats_owned.iter().map(String::as_str).collect();
70    let one = "https://cdn.example.com/path/9999/asset/file/deep/name.bin";
71    let n = 40_000;
72    let s = s_from(vec![one; n]);
73
74    let _ = s.str().startswith_any(&pats).unwrap(); // warmup
75
76    let t = Instant::now();
77    let r = s.str().startswith_any(&pats).unwrap();
78    let d = t.elapsed();
79    assert_eq!(r.len(), n);
80
81    println!(
82        "TIMING n={n} npats={} startswith_any={:.3}ms",
83        pats.len(),
84        d.as_secs_f64() * 1e3
85    );
86}
Source

pub fn is_empty(&self) -> bool

Return true if this Series has zero elements.

Source

pub fn align( &self, other: &Self, mode: AlignMode, ) -> Result<(Self, Self), FrameError>

Align two Series by their indexes, returning a pair aligned to a common index.

Matches pd.Series.align(other, join='inner'|'left'|'right'|'outer'). Uses duplicate-aware alignment for outer joins when duplicate labels exist.

Source

pub fn combine_first(&self, other: &Self) -> Result<Self, FrameError>

Fill missing values from other.

Matches pd.Series.combine_first(other): uses outer alignment, then for each position takes self’s value if non-null, else other’s.

Source

pub fn append(&self, other: &Self) -> Result<Self, FrameError>

Append another Series to this one.

Matches pd.Series.append(other) (deprecated but common). Concatenates values and index labels.

Source

pub fn first_valid_index(&self) -> Option<IndexLabel>

Return the index label of the first non-null value.

Matches pd.Series.first_valid_index().

Source

pub fn last_valid_index(&self) -> Option<IndexLabel>

Return the index label of the last non-null value.

Matches pd.Series.last_valid_index().

Source

pub fn update(&self, other: &Self) -> Result<Self, FrameError>

Update values using non-null values from another Series.

Analogous to pandas.Series.update(other). Only updates values at matching index labels where other has non-null values. The result retains self’s index (no new labels added from other).

Source

pub fn reindex(&self, new_labels: Vec<IndexLabel>) -> Result<Self, FrameError>

Reindex to a new set of labels, filling missing positions with null.

Matches pd.Series.reindex(new_index).

Source

pub fn reindex_with_method( &self, new_labels: Vec<IndexLabel>, method: &str, ) -> Result<Self, FrameError>

Reindex to new labels with a fill method for introduced NaN.

Matches s.reindex(new_labels, method='ffill'|'bfill'). After reindexing, missing values are filled using the specified method.

Source

pub fn gt(&self, other: &Self) -> Result<Self, FrameError>

Element-wise greater-than. Matches series > other.

Source

pub fn lt(&self, other: &Self) -> Result<Self, FrameError>

Element-wise less-than. Matches series < other.

Source

pub fn eq_series(&self, other: &Self) -> Result<Self, FrameError>

Element-wise equality. Matches series == other.

Source

pub fn eq(&self, other: &Self) -> Result<Self, FrameError>

pandas method alias for element-wise equality.

Matches pd.Series.eq(other).

Source

pub fn ne_series(&self, other: &Self) -> Result<Self, FrameError>

Element-wise not-equal. Matches series != other.

Source

pub fn ne(&self, other: &Self) -> Result<Self, FrameError>

pandas method alias for element-wise inequality.

Matches pd.Series.ne(other).

Source

pub fn ge(&self, other: &Self) -> Result<Self, FrameError>

Element-wise greater-or-equal. Matches series >= other.

Source

pub fn le(&self, other: &Self) -> Result<Self, FrameError>

Element-wise less-or-equal. Matches series <= other.

Source

pub fn allclose( &self, other: &Self, rtol: f64, atol: f64, ) -> Result<bool, FrameError>

Check if two series are element-wise equal within a tolerance.

Matches np.allclose(s1, s2, rtol, atol).

Source

pub fn compare_scalar( &self, scalar: &Scalar, op: ComparisonOp, ) -> Result<Self, FrameError>

Compare each element against a scalar value.

Matches series > 5 (broadcast scalar comparison).

Source

pub fn eq_scalar(&self, scalar: &Scalar) -> Result<Self, FrameError>

Element-wise == scalar.

Source

pub fn ne_scalar(&self, scalar: &Scalar) -> Result<Self, FrameError>

Element-wise != scalar.

Source

pub fn gt_scalar(&self, scalar: &Scalar) -> Result<Self, FrameError>

Element-wise > scalar.

Source

pub fn ge_scalar(&self, scalar: &Scalar) -> Result<Self, FrameError>

Element-wise >= scalar.

Source

pub fn lt_scalar(&self, scalar: &Scalar) -> Result<Self, FrameError>

Element-wise < scalar.

Source

pub fn le_scalar(&self, scalar: &Scalar) -> Result<Self, FrameError>

Element-wise <= scalar.

Source

pub fn equals(&self, other: &Self) -> bool

Test whether two Series are equal (same name, index, and values).

Analogous to pandas.Series.equals(other). Returns true only if both Series have identical names, index labels, and values (including NaN == NaN semantics for null positions).

Source

pub fn and(&self, other: &Self) -> Result<Self, FrameError>

Element-wise boolean AND with outer index alignment.

Uses three-valued logic compatible with nullable boolean semantics:

  • false & x == false
  • true & true == true
  • true & null == null, null & null == null
Source

pub fn or(&self, other: &Self) -> Result<Self, FrameError>

Element-wise boolean OR with outer index alignment.

Uses three-valued logic compatible with nullable boolean semantics:

  • true | x == true
  • false | false == false
  • false | null == null, null | null == null
Source

pub fn not(&self) -> Result<Self, FrameError>

Element-wise boolean NOT.

Missing values remain missing.

Source

pub fn filter(&self, mask: &Self) -> Result<Self, FrameError>

Select elements where mask is True.

Matches series[bool_series] boolean indexing in pandas. The mask must be a Bool-typed Series. Indexes are aligned before applying the mask. Missing values in the mask are treated as False.

Source

pub fn loc(&self, labels: &[IndexLabel]) -> Result<Self, FrameError>

Label-based selection for a list of labels.

Matches series.loc[[...]] for list-like selectors. Labels are returned in selector order and duplicate labels in the selector are preserved. If a requested label does not exist, this fails closed.

Examples found in repository?
examples/bench_loc.rs (lines 28-32)
22fn golden() -> String {
23    let mut out = String::new();
24    // Duplicate index label 10 at positions 0 and 2.
25    let s = s_from(vec![10, 20, 10, 30], vec![100, 200, 300, 400]);
26    // Selector order [10, 30, 20]; 10 returns both matches (asc position).
27    let r = s
28        .loc(&[
29            IndexLabel::Int64(10),
30            IndexLabel::Int64(30),
31            IndexLabel::Int64(20),
32        ])
33        .unwrap();
34    out.push_str(&format!("labels={:?}\n", r.index().labels()));
35    out.push_str(&format!("values={:?}\n", r.values()));
36    // Duplicate selector entries preserved.
37    let r2 = s
38        .loc(&[IndexLabel::Int64(20), IndexLabel::Int64(20)])
39        .unwrap();
40    out.push_str(&format!("dup_sel_values={:?}\n", r2.values()));
41    // Missing label fails closed.
42    let err = s.loc(&[IndexLabel::Int64(99)]);
43    out.push_str(&format!("missing_is_err={}\n", err.is_err()));
44    out
45}
46
47fn main() {
48    let g = golden();
49    print!("GOLDEN_BEGIN\n{g}GOLDEN_END\n");
50
51    let n: usize = 60_000;
52    let labels: Vec<i64> = (0..n as i64).collect();
53    let vals: Vec<i64> = (0..n as i64).map(|v| v * 2).collect();
54    let s = s_from(labels.clone(), vals);
55    let selector: Vec<IndexLabel> = (0..n as i64).map(IndexLabel::Int64).collect();
56
57    let t = Instant::now();
58    let r = s.loc(&selector).unwrap();
59    let d = t.elapsed();
60    assert_eq!(r.len(), n);
61
62    println!("TIMING n={n} m={n} loc={:.3}ms", d.as_secs_f64() * 1e3);
63}
Source

pub fn iloc(&self, positions: &[i64]) -> Result<Self, FrameError>

Position-based selection for a list of integer positions.

Matches series.iloc[[...]] for list-like selectors. Positions are returned in selector order and duplicates are preserved. Negative positions are resolved from the end of the Series.

Examples found in repository?
examples/bench_iloc_gather.rs (line 30)
26fn golden() -> String {
27    let mut out = String::new();
28    let s = s_i64(vec![10, 20, 30, 40, 50]);
29    // reorder + negative indices + duplicates
30    let r = s.iloc(&[4, 0, -1, 2, -5, 2]).unwrap();
31    out.push_str(&format!("i64_lbls={:?}\n", r.index().labels()));
32    out.push_str(&format!("i64_vals={:?}\n", r.values()));
33
34    // Float64 incl NaN
35    let f = s_scalars(vec![
36        Scalar::Float64(1.5),
37        Scalar::Float64(f64::NAN),
38        Scalar::Float64(-3.0),
39    ]);
40    out.push_str(&format!("f64={:?}\n", f.iloc(&[2, 1, 0]).unwrap().values()));
41
42    // Nullable Int64 (Null present => not all-valid path)
43    let ni = s_scalars(vec![
44        Scalar::Int64(7),
45        Scalar::Null(NullKind::NaN),
46        Scalar::Int64(9),
47    ]);
48    out.push_str(&format!("ni={:?}\n", ni.iloc(&[1, 2, 0]).unwrap().values()));
49
50    // Utf8 + Bool
51    let u = s_scalars(
52        vec!["a", "b", "c"]
53            .into_iter()
54            .map(|x| Scalar::Utf8(x.into()))
55            .collect(),
56    );
57    out.push_str(&format!("utf8={:?}\n", u.iloc(&[2, -3]).unwrap().values()));
58    let b = s_scalars(vec![Scalar::Bool(true), Scalar::Bool(false)]);
59    out.push_str(&format!(
60        "bool={:?}\n",
61        b.iloc(&[1, 0, 1]).unwrap().values()
62    ));
63
64    // Out-of-bounds errors
65    out.push_str(&format!("oob_err={}\n", s.iloc(&[99]).is_err()));
66    out
67}
68
69fn main() {
70    let g = golden();
71    print!("GOLDEN_BEGIN\n{g}GOLDEN_END\n");
72
73    let n: usize = 1_000_000;
74    let s = s_i64((0..n as i64).map(|v| v * 2).collect());
75    // Shuffled full permutation (LCG).
76    let mut x: u64 = 0xdead_beef;
77    let mut pos: Vec<i64> = (0..n as i64).collect();
78    for i in (1..n).rev() {
79        x = x
80            .wrapping_mul(6364136223846793005)
81            .wrapping_add(1442695040888963407);
82        let j = (x >> 16) as usize % (i + 1);
83        pos.swap(i, j);
84    }
85
86    let _ = s.iloc(&pos).unwrap(); // warmup
87
88    let t = Instant::now();
89    let r = s.iloc(&pos).unwrap();
90    let d = t.elapsed();
91    assert_eq!(r.len(), n);
92
93    println!("TIMING n={n} iloc={:.3}ms", d.as_secs_f64() * 1e3);
94}
Source

pub fn loc_bool(&self, mask: &[bool]) -> Result<Self, FrameError>

Label-based boolean mask selection.

Matches series.loc[bool_array] in pandas. The boolean mask must have the same length as the Series. Rows where the mask is True are kept; False and Null mask entries are excluded.

Source

pub fn iloc_bool(&self, mask: &[bool]) -> Result<Self, FrameError>

Position-based boolean mask selection.

Matches series.iloc[bool_array] in pandas. The boolean mask must have the same length as the Series. Semantically identical to loc_bool for Series (position and label filtering coincide on the same axis).

Source

pub fn loc_bool_series(&self, mask: &Self) -> Result<Self, FrameError>

Label-based boolean Series mask selection with index alignment.

Matches series.loc[bool_series] in pandas, which is the most common usage pattern (e.g., s.loc[s > 5]). The mask Series is aligned with this Series by index before filtering. Missing mask values are treated as False. This is an alias for Series::filter.

Source

pub fn iloc_bool_series(&self, mask: &Self) -> Result<Self, FrameError>

Position-based boolean Series mask selection with index alignment.

Matches series.iloc[bool_series] in pandas. Semantically identical to loc_bool_series (delegates to filter).

Source

pub fn loc_slice( &self, start: Option<&IndexLabel>, stop: Option<&IndexLabel>, ) -> Result<Self, FrameError>

Label-based slice selection (inclusive on both ends).

Matches series.loc[start:stop] in pandas. Both start and stop are optional. When present, the slice is inclusive on both endpoints (pandas semantics for label-based slicing). Returns rows in their original order.

Source

pub fn iloc_slice( &self, start: Option<i64>, stop: Option<i64>, ) -> Result<Self, FrameError>

Position-based slice selection (exclusive end, like Python range).

Matches series.iloc[start:stop] in pandas. The start is inclusive and stop is exclusive (standard Python slice semantics). Negative values are resolved from the end. Both are optional.

Source

pub fn sort_index(&self, ascending: bool) -> Result<Self, FrameError>

Return a new Series sorted by index labels.

Matches s.sort_index(ascending=...) for the current 1D IndexLabel model.

Examples found in repository?
examples/bench_sort_index.rs (line 36)
32fn golden() -> String {
33    let mut out = String::new();
34    // Duplicate labels 1 and 3 with distinct values prove stable tie order.
35    let s = series(vec![3, 1, 2, 1, 3], vec![10, 20, 30, 40, 50]);
36    let asc = s.sort_index(true).unwrap();
37    out.push_str(&format!("s_asc_labels={:?}\n", asc.index().labels()));
38    out.push_str(&format!("s_asc_vals={:?}\n", asc.values()));
39    let desc = s.sort_index(false).unwrap();
40    out.push_str(&format!("s_desc_labels={:?}\n", desc.index().labels()));
41    out.push_str(&format!("s_desc_vals={:?}\n", desc.values()));
42
43    // Negative + zero labels.
44    let s2 = series(vec![0, -5, 7, -5, 0], vec![1, 2, 3, 4, 5]);
45    let a2 = s2.sort_index(true).unwrap();
46    out.push_str(&format!("s2_asc_labels={:?}\n", a2.index().labels()));
47    out.push_str(&format!("s2_asc_vals={:?}\n", a2.values()));
48
49    let df = frame(vec![3, 1, 2, 1, 3], vec![10, 20, 30, 40, 50]);
50    let dfa = df.sort_index(true).unwrap();
51    out.push_str(&format!("df_asc_labels={:?}\n", dfa.index().labels()));
52    out.push_str(&format!(
53        "df_asc_v={:?}\n",
54        dfa.columns().get("v").unwrap().values()
55    ));
56    let dfd = df.sort_index(false).unwrap();
57    out.push_str(&format!("df_desc_labels={:?}\n", dfd.index().labels()));
58    out.push_str(&format!(
59        "df_desc_v={:?}\n",
60        dfd.columns().get("v").unwrap().values()
61    ));
62    out
63}
64
65fn main() {
66    let g = golden();
67    print!("GOLDEN_BEGIN\n{g}GOLDEN_END\n");
68
69    let n: usize = 200_000;
70    // Shuffled (LCG) i64 index so it is unsorted and Int64-typed.
71    let mut x: u64 = 0x1234_5678;
72    let labels: Vec<i64> = (0..n)
73        .map(|_| {
74            x = x
75                .wrapping_mul(6364136223846793005)
76                .wrapping_add(1442695040888963407);
77            (x >> 16) as i64 % (n as i64)
78        })
79        .collect();
80    let vals: Vec<i64> = (0..n as i64).collect();
81    let s = series(labels, vals);
82
83    // warmup
84    let _ = s.sort_index(true).unwrap();
85
86    let t = Instant::now();
87    let r = s.sort_index(true).unwrap();
88    let d = t.elapsed();
89    assert_eq!(r.len(), n);
90
91    println!("TIMING n={n} sort_index={:.3}ms", d.as_secs_f64() * 1e3);
92}
Source

pub fn sort_values(&self, ascending: bool) -> Result<Self, FrameError>

Return a new Series sorted by values.

Matches s.sort_values(ascending=...) with na_position='last'.

Examples found in repository?
examples/bench_sort_values_gather.rs (line 32)
26fn golden() -> String {
27    let mut out = String::new();
28    // Int64 ascending/descending with ties (stable).
29    let s = s_i64(vec![3, 1, 2, 1, 3]);
30    out.push_str(&format!(
31        "i64_asc={:?}\n",
32        s.sort_values(true).unwrap().values()
33    ));
34    out.push_str(&format!(
35        "i64_desc={:?}\n",
36        s.sort_values(false).unwrap().values()
37    ));
38
39    // Float64 with NaN (NaN sorts last under na_position='last').
40    let f = s_scalars(vec![
41        Scalar::Float64(2.5),
42        Scalar::Float64(f64::NAN),
43        Scalar::Float64(-1.0),
44        Scalar::Float64(2.5),
45    ]);
46    out.push_str(&format!(
47        "f64_asc={:?}\n",
48        f.sort_values(true).unwrap().values()
49    ));
50
51    // Nullable Int64 (Null mixed in) via na_position first/last.
52    let ni = s_scalars(vec![
53        Scalar::Int64(5),
54        Scalar::Null(NullKind::NaN),
55        Scalar::Int64(-2),
56        Scalar::Int64(5),
57    ]);
58    out.push_str(&format!(
59        "ni_last={:?}\n",
60        ni.sort_values_na(true, "last").unwrap().values()
61    ));
62    out.push_str(&format!(
63        "ni_first={:?}\n",
64        ni.sort_values_na(true, "first").unwrap().values()
65    ));
66
67    // Utf8.
68    let u = s_scalars(
69        vec!["banana", "apple", "cherry", "apple"]
70            .into_iter()
71            .map(|x| Scalar::Utf8(x.to_string()))
72            .collect(),
73    );
74    out.push_str(&format!(
75        "utf8_asc={:?}\n",
76        u.sort_values(true).unwrap().values()
77    ));
78
79    // Bool.
80    let b = s_scalars(vec![
81        Scalar::Bool(true),
82        Scalar::Bool(false),
83        Scalar::Bool(true),
84    ]);
85    out.push_str(&format!(
86        "bool_asc={:?}\n",
87        b.sort_values(true).unwrap().values()
88    ));
89    out
90}
91
92fn main() {
93    let g = golden();
94    print!("GOLDEN_BEGIN\n{g}GOLDEN_END\n");
95
96    let n: usize = 1_000_000;
97    let mut x: u64 = 0x9e37_79b9;
98    let vals: Vec<i64> = (0..n)
99        .map(|_| {
100            x = x
101                .wrapping_mul(6364136223846793005)
102                .wrapping_add(1442695040888963407);
103            (x >> 16) as i64 % 1_000_000
104        })
105        .collect();
106    let s = s_i64(vals);
107
108    let _ = s.sort_values(true).unwrap(); // warmup
109
110    let t = Instant::now();
111    let r = s.sort_values(true).unwrap();
112    let d = t.elapsed();
113    assert_eq!(r.len(), n);
114
115    println!("TIMING n={n} sort_values={:.3}ms", d.as_secs_f64() * 1e3);
116}
Source

pub fn sort_values_na( &self, ascending: bool, na_position: &str, ) -> Result<Self, FrameError>

Return a new Series sorted by values with explicit NA position.

Matches s.sort_values(ascending=..., na_position='first'|'last').

Examples found in repository?
examples/bench_sort_values_gather.rs (line 60)
26fn golden() -> String {
27    let mut out = String::new();
28    // Int64 ascending/descending with ties (stable).
29    let s = s_i64(vec![3, 1, 2, 1, 3]);
30    out.push_str(&format!(
31        "i64_asc={:?}\n",
32        s.sort_values(true).unwrap().values()
33    ));
34    out.push_str(&format!(
35        "i64_desc={:?}\n",
36        s.sort_values(false).unwrap().values()
37    ));
38
39    // Float64 with NaN (NaN sorts last under na_position='last').
40    let f = s_scalars(vec![
41        Scalar::Float64(2.5),
42        Scalar::Float64(f64::NAN),
43        Scalar::Float64(-1.0),
44        Scalar::Float64(2.5),
45    ]);
46    out.push_str(&format!(
47        "f64_asc={:?}\n",
48        f.sort_values(true).unwrap().values()
49    ));
50
51    // Nullable Int64 (Null mixed in) via na_position first/last.
52    let ni = s_scalars(vec![
53        Scalar::Int64(5),
54        Scalar::Null(NullKind::NaN),
55        Scalar::Int64(-2),
56        Scalar::Int64(5),
57    ]);
58    out.push_str(&format!(
59        "ni_last={:?}\n",
60        ni.sort_values_na(true, "last").unwrap().values()
61    ));
62    out.push_str(&format!(
63        "ni_first={:?}\n",
64        ni.sort_values_na(true, "first").unwrap().values()
65    ));
66
67    // Utf8.
68    let u = s_scalars(
69        vec!["banana", "apple", "cherry", "apple"]
70            .into_iter()
71            .map(|x| Scalar::Utf8(x.to_string()))
72            .collect(),
73    );
74    out.push_str(&format!(
75        "utf8_asc={:?}\n",
76        u.sort_values(true).unwrap().values()
77    ));
78
79    // Bool.
80    let b = s_scalars(vec![
81        Scalar::Bool(true),
82        Scalar::Bool(false),
83        Scalar::Bool(true),
84    ]);
85    out.push_str(&format!(
86        "bool_asc={:?}\n",
87        b.sort_values(true).unwrap().values()
88    ));
89    out
90}
Source

pub fn head(&self, n: i64) -> Result<Self, FrameError>

Return the first n rows.

Matches s.head(n). If n is negative, this returns all rows except the last -n rows.

Source

pub fn tail(&self, n: i64) -> Result<Self, FrameError>

Return the last n rows.

Matches s.tail(n). If n is negative, this returns all rows except the first -n rows.

Source

pub fn fillna(&self, fill_value: &Scalar) -> Result<Self, FrameError>

Fill missing values with a scalar.

Matches pd.Series.fillna(value).

Source

pub fn fillna_limit( &self, fill_value: &Scalar, limit: usize, ) -> Result<Self, FrameError>

Fill missing values with fill_value, filling at most limit consecutive NaN positions.

Matches series.fillna(value, limit=N).

Source

pub fn ffill(&self, limit: Option<usize>) -> Result<Self, FrameError>

Forward-fill missing values (propagate last valid observation forward).

Matches pd.Series.ffill() / pd.Series.fillna(method='ffill'). An optional limit caps the maximum number of consecutive NaNs to fill.

Source

pub fn bfill(&self, limit: Option<usize>) -> Result<Self, FrameError>

Back-fill missing values (propagate next valid observation backward).

Matches pd.Series.bfill() / pd.Series.fillna(method='bfill'). An optional limit caps the maximum number of consecutive NaNs to fill.

Source

pub fn pad(&self, limit: Option<usize>) -> Result<Self, FrameError>

Deprecated pandas alias for Self::ffill. Matches pd.Series.pad(limit=None). Per br-frankenpandas-qn0bj — pandas kept pad for backwards compatibility after promoting ffill.

Source

pub fn backfill(&self, limit: Option<usize>) -> Result<Self, FrameError>

Deprecated pandas alias for Self::bfill. Matches pd.Series.backfill(limit=None). Per br-frankenpandas-qn0bj.

Source

pub fn bool(&self) -> Result<bool, FrameError>

pandas-named alias for Self::bool_. Matches pd.Series.bool(). Per br-frankenpandas-qn0bj. bool is a Rust keyword; the public name uses the raw-identifier form. Callers from Rust write series.r#bool(); the Python FFI surface exposes bare bool.

Source

pub fn interpolate(&self) -> Result<Self, FrameError>

Linearly interpolate missing values.

Matches pd.Series.interpolate(method='linear'). Non-numeric values and leading/trailing NaNs are left as NaN. Only interior NaN gaps between two valid numeric values are filled.

Source

pub fn interpolate_method(&self, method: &str) -> Result<Self, FrameError>

Interpolate missing values using the specified method.

Matches s.interpolate(method='linear'|'nearest'|'zero').

  • linear: linear interpolation between bounding valid values (default)
  • nearest: use the nearest valid value
  • zero: use the left bounding value (step function / zero-order hold)
Source

pub fn dropna(&self) -> Result<Self, FrameError>

Remove entries with missing values.

Matches pd.Series.dropna().

Source

pub fn drop(&self, labels: &[IndexLabel]) -> Result<Self, FrameError>

Drop entries by index label.

Matches pd.Series.drop(labels). Returns a new Series excluding the specified index labels.

Source

pub fn asof(&self, label: &IndexLabel) -> Option<&Scalar>

Find the last non-NaN value at or before the given label.

Matches pd.Series.asof(where). The index must be sorted. Scans backwards from the position of where (or the last position before it) for the first non-missing value.

Source

pub fn isna(&self) -> Result<Self, FrameError>

Return a boolean mask where missing values are true.

Matches pd.Series.isna().

Source

pub fn isnull(&self) -> Result<Self, FrameError>

Alias for isna.

Matches pd.Series.isnull().

Source

pub fn notna(&self) -> Result<Self, FrameError>

Return a boolean mask where non-missing values are true.

Matches pd.Series.notna().

Source

pub fn notnull(&self) -> Result<Self, FrameError>

Alias for notna.

Matches pd.Series.notnull().

Source

pub fn count(&self) -> usize

Return the number of non-null elements.

Matches pd.Series.count().

Source

pub fn count_nonzero(&self) -> usize

Return the number of non-zero elements.

Matches np.count_nonzero(series).

Source

pub fn value_counts(&self) -> Result<Self, FrameError>

Source

pub fn value_counts_with_options( &self, normalize: bool, sort: bool, ascending: bool, dropna: bool, ) -> Result<Self, FrameError>

Value counts with full pandas parameter support.

Matches pd.Series.value_counts(normalize, sort, ascending, dropna).

Source

pub fn value_counts_bins(&self, bins: usize) -> Result<Self, FrameError>

Count values binned into equal-width intervals.

Matches pd.Series.value_counts(bins=n). Divides the numeric range into bins equal-width intervals using cut, then counts values per interval. Returns a Series indexed by interval labels, sorted descending by count.

Source

pub fn is_unique(&self) -> bool

Check if all values in the Series are unique (no duplicates).

Matches pd.Series.is_unique.

Source

pub fn has_duplicates(&self) -> bool

Return whether the Series contains any duplicated values.

Matches pd.Series.has_duplicates. Semantically the complement of is_unique: multiple null entries count as duplicates, consistent with is_unique’s null_count <= 1 rule.

Source

pub fn is_monotonic_increasing(&self) -> bool

Check if values are monotonically increasing (non-decreasing).

Matches pd.Series.is_monotonic_increasing.

Source

pub fn is_monotonic(&self) -> bool

Alias for is_monotonic_increasing.

Source

pub fn is_monotonic_decreasing(&self) -> bool

Check if values are monotonically decreasing (non-increasing).

Matches pd.Series.is_monotonic_decreasing.

Source§

impl Series

Source

pub fn apply<F>(&self, func: F) -> Result<Series, FrameError>
where F: Fn(&Scalar) -> Scalar,

Apply a custom function to each element of the Series.

Matches pd.Series.apply(func).

Source

pub fn map_func<F>(&self, func: F) -> Result<Series, FrameError>
where F: Fn(&Scalar) -> Scalar,

Map values of a Series using an input mapping or function.

Matches pd.Series.map(arg).

Source

pub fn unique(&self) -> Vec<Scalar>

Return unique non-null values in first-seen order.

Matches pd.Series.unique().

Values are returned in first-seen order (pandas preserves appearance order, not sort order). A single missing marker is retained: pandas’ Series([1, NaN, 2, NaN, 1]).unique() returns [1, NaN, 2], not [1, 2] — NaN counts as one distinct category.

Source

pub fn nunique(&self) -> usize

Count of unique non-null values.

Matches pd.Series.nunique().

Source

pub fn nunique_with_dropna(&self, dropna: bool) -> usize

Count of unique values with explicit null counting control.

Matches pd.Series.nunique(dropna=...).

Source

pub fn map(&self, mapping: &[(Scalar, Scalar)]) -> Result<Self, FrameError>

Map values using a dict-like mapping. Unmapped values become NaN.

Matches pd.Series.map(dict).

Source

pub fn map_callable<F>(&self, func: F) -> Result<Self, FrameError>
where F: FnMut(&Scalar) -> Scalar,

Map values by applying a user function element-wise.

Matches pd.Series.map(callable) — the function form rather than the dict form of map. Missing values pass through as Null(NaN) without invoking func (matches pandas na_action='ignore' default).

Source

pub fn map_with_default( &self, mapping: &[(Scalar, Scalar)], default: &Scalar, ) -> Result<Self, FrameError>

Map values using a lookup table with a default for unmapped keys.

Matches pd.Series.map(dict, na_action=None) where unmapped values use the provided default instead of NaN.

Source

pub fn map_series(&self, mapper: &Series) -> Result<Self, FrameError>

Map values using another Series as a lookup table.

Matches pd.Series.map(other_series). The mapper series’ index labels are matched against self’s values. For each value in self, if it matches a label in mapper’s index, the corresponding mapper value is used; otherwise NaN.

Source

pub fn replace( &self, replacements: &[(Scalar, Scalar)], ) -> Result<Self, FrameError>

Replace specific values with substitutions.

Matches pd.Series.replace(to_replace, value) for scalar pairs.

Source

pub fn replace_map( &self, mapping: &HashMap<String, Scalar>, ) -> Result<Self, FrameError>

Replace values using a HashMap mapping.

Matches series.replace({old1: new1, old2: new2}).

Source

pub fn replace_regex(&self, pat: &str, repl: &str) -> Result<Self, FrameError>

Replace string values matching a regex pattern.

Matches series.replace(regex=True) or series.str.replace(pat, repl, regex=True). Non-Utf8 values pass through unchanged.

Source

pub fn quantile(&self, q: f64) -> Result<Scalar, FrameError>

Compute the q-th quantile (0.0 to 1.0) using linear interpolation.

Matches pd.Series.quantile(q).

Source

pub fn quantile_with_interpolation( &self, q: f64, interpolation: &str, ) -> Result<Scalar, FrameError>

Compute the q-th quantile with explicit interpolation mode.

Per br-frankenpandas-a56003: matches pd.Series.quantile(q, interpolation). Modes: “linear” (default), “lower”, “higher”, “nearest”, “midpoint”.

Source

pub fn astype(&self, dtype: DType) -> Result<Self, FrameError>

Cast values to a target dtype.

Matches series.astype(dtype) for scalar dtypes.

Source

pub fn astype_safe( &self, dtype: DType, errors: &str, ) -> Result<Self, FrameError>

Cast with error handling.

Matches pd.Series.astype(dtype, errors='coerce'|'raise').

  • errors="raise" (default): same as astype()
  • errors="coerce": values that fail conversion become NaN
Source

pub fn clip( &self, lower: Option<f64>, upper: Option<f64>, ) -> Result<Self, FrameError>

Clip values to [lower, upper].

Matches pd.Series.clip(lower, upper). NaN values pass through unchanged.

Source

pub fn clip_lower(&self, threshold: f64) -> Result<Self, FrameError>

Clip values below a threshold.

Source

pub fn clip_upper(&self, threshold: f64) -> Result<Self, FrameError>

Clip values above a threshold.

Source

pub fn clip_with_series( &self, lower: Option<&Self>, upper: Option<&Self>, ) -> Result<Self, FrameError>

Clip values using element-wise Series bounds.

Matches series.clip(lower=series, upper=series). Each element is clipped independently using the corresponding bound.

Source

pub fn add_prefix(&self, prefix: &str) -> Result<Self, FrameError>

Return a new Series with prefixed index labels.

Matches pd.Series.add_prefix(prefix): the index labels are stringified and prefixed; the Series name and values are unchanged.

Source

pub fn add_suffix(&self, suffix: &str) -> Result<Self, FrameError>

Return a new Series with suffixed index labels.

Matches pd.Series.add_suffix(suffix): the index labels are stringified and suffixed; the Series name and values are unchanged.

Source

pub fn abs(&self) -> Result<Self, FrameError>

Absolute value of each element.

Matches pd.Series.abs(). Numeric, boolean, and timedelta dtypes retain their pandas-observable dtype; missing values pass through.

Source

pub fn absolute(&self) -> Result<Self, FrameError>

Alias for abs. Matches np.absolute.

Source

pub fn fabs(&self) -> Result<Self, FrameError>

Absolute value of floating-point elements.

Matches np.fabs(series). Same as abs() but explicitly for floats.

Source

pub fn round(&self, decimals: i32) -> Result<Self, FrameError>

Round each element to decimals decimal places.

Matches pd.Series.round(decimals). NaN values pass through.

Source

pub fn around(&self, decimals: i32) -> Result<Self, FrameError>

Alias for round. Matches np.around.

Source

pub fn floor(&self) -> Result<Self, FrameError>

Floor each element (round toward negative infinity).

Matches np.floor(series). NaN values pass through.

Source

pub fn ceil(&self) -> Result<Self, FrameError>

Ceiling of each element (round toward positive infinity).

Matches np.ceil(series). NaN values pass through.

Source

pub fn trunc(&self) -> Result<Self, FrameError>

Truncate each element toward zero.

Matches np.trunc(series). NaN values pass through.

Source

pub fn sqrt(&self) -> Result<Self, FrameError>

Element-wise square root.

Matches np.sqrt(series). NaN values pass through.

Source

pub fn exp(&self) -> Result<Self, FrameError>

Element-wise exponential (e^x).

Matches np.exp(series). NaN values pass through.

Source

pub fn log(&self) -> Result<Self, FrameError>

Element-wise natural logarithm.

Matches np.log(series). NaN values pass through.

Source

pub fn log10(&self) -> Result<Self, FrameError>

Element-wise base-10 logarithm.

Matches np.log10(series). NaN values pass through.

Source

pub fn log2(&self) -> Result<Self, FrameError>

Element-wise base-2 logarithm.

Matches np.log2(series). NaN values pass through.

Source

pub fn sin(&self) -> Result<Self, FrameError>

Element-wise sine.

Matches np.sin(series). NaN values pass through.

Source

pub fn cos(&self) -> Result<Self, FrameError>

Element-wise cosine.

Matches np.cos(series). NaN values pass through.

Source

pub fn tan(&self) -> Result<Self, FrameError>

Element-wise tangent.

Matches np.tan(series). NaN values pass through.

Source

pub fn sinh(&self) -> Result<Self, FrameError>

Element-wise hyperbolic sine.

Matches np.sinh(series). NaN values pass through.

Source

pub fn cosh(&self) -> Result<Self, FrameError>

Element-wise hyperbolic cosine.

Matches np.cosh(series). NaN values pass through.

Source

pub fn tanh(&self) -> Result<Self, FrameError>

Element-wise hyperbolic tangent.

Matches np.tanh(series). NaN values pass through.

Source

pub fn arcsin(&self) -> Result<Self, FrameError>

Element-wise inverse sine.

Matches np.arcsin(series). NaN values pass through.

Source

pub fn arccos(&self) -> Result<Self, FrameError>

Element-wise inverse cosine.

Matches np.arccos(series). NaN values pass through.

Source

pub fn arctan(&self) -> Result<Self, FrameError>

Element-wise inverse tangent.

Matches np.arctan(series). NaN values pass through.

Source

pub fn arcsinh(&self) -> Result<Self, FrameError>

Element-wise inverse hyperbolic sine.

Matches np.arcsinh(series). NaN values pass through.

Source

pub fn arccosh(&self) -> Result<Self, FrameError>

Element-wise inverse hyperbolic cosine.

Matches np.arccosh(series). NaN values pass through.

Source

pub fn arctanh(&self) -> Result<Self, FrameError>

Element-wise inverse hyperbolic tangent.

Matches np.arctanh(series). NaN values pass through.

Source

pub fn asin(&self) -> Result<Self, FrameError>

Alias for arcsin. Matches Rust/math convention.

Source

pub fn acos(&self) -> Result<Self, FrameError>

Alias for arccos. Matches Rust/math convention.

Source

pub fn atan(&self) -> Result<Self, FrameError>

Alias for arctan. Matches Rust/math convention.

Source

pub fn asinh(&self) -> Result<Self, FrameError>

Alias for arcsinh. Matches Rust/math convention.

Source

pub fn acosh(&self) -> Result<Self, FrameError>

Alias for arccosh. Matches Rust/math convention.

Source

pub fn atanh(&self) -> Result<Self, FrameError>

Alias for arctanh. Matches Rust/math convention.

Source

pub fn expm1(&self) -> Result<Self, FrameError>

Element-wise exp(x) - 1 with improved precision for small x.

Matches np.expm1(series). NaN values pass through.

Source

pub fn log1p(&self) -> Result<Self, FrameError>

Element-wise log(1 + x) with improved precision for small x.

Matches np.log1p(series). NaN values pass through.

Source

pub fn cbrt(&self) -> Result<Self, FrameError>

Element-wise cube root.

Matches np.cbrt(series). NaN values pass through.

Source

pub fn sign(&self) -> Result<Self, FrameError>

Element-wise sign (-1, 0, or 1).

Matches np.sign(series). NaN values pass through.

Source

pub fn signbit(&self) -> Result<Self, FrameError>

Element-wise sign bit (true if negative).

Matches np.signbit(series). NaN values pass through.

Source

pub fn radians(&self) -> Result<Self, FrameError>

Convert angles from degrees to radians.

Matches np.radians(series) / np.deg2rad(series).

Source

pub fn deg2rad(&self) -> Result<Self, FrameError>

Alias for radians(). Matches np.deg2rad(series).

Source

pub fn degrees(&self) -> Result<Self, FrameError>

Convert angles from radians to degrees.

Matches np.degrees(series) / np.rad2deg(series).

Source

pub fn rad2deg(&self) -> Result<Self, FrameError>

Alias for degrees(). Matches np.rad2deg(series).

Source

pub fn reciprocal(&self) -> Result<Self, FrameError>

Element-wise reciprocal (1/x).

Matches np.reciprocal(series). NaN values pass through.

Source

pub fn square(&self) -> Result<Self, FrameError>

Element-wise square (x^2).

Matches np.square(series). NaN values pass through.

Source

pub fn rint(&self) -> Result<Self, FrameError>

Round to nearest integer (banker’s rounding).

Matches np.rint(series). NaN values pass through.

Source

pub fn fix(&self) -> Result<Self, FrameError>

Round toward zero (alias for trunc).

Matches np.fix(series). NaN values pass through.

Source

pub fn isfinite(&self) -> Result<Self, FrameError>

Element-wise check for finite values.

Matches np.isfinite(series). Returns boolean Series.

Source

pub fn isinf(&self) -> Result<Self, FrameError>

Element-wise check for infinite values.

Matches np.isinf(series). Returns boolean Series.

Source

pub fn isnan(&self) -> Result<Self, FrameError>

Element-wise check for NaN values.

Matches np.isnan(series). Returns boolean Series.

Source

pub fn isneginf(&self) -> Result<Self, FrameError>

Element-wise check for negative infinity.

Matches np.isneginf(series). Returns boolean Series.

Source

pub fn isposinf(&self) -> Result<Self, FrameError>

Element-wise check for positive infinity.

Matches np.isposinf(series). Returns boolean Series.

Source

pub fn nan_to_num(&self) -> Result<Self, FrameError>

Replace NaN with zero and infinity with large finite numbers.

Matches np.nan_to_num(series).

Source

pub fn neg(&self) -> Result<Self, FrameError>

Element-wise negation (-x).

Matches np.negative(series) / -series.

Source

pub fn negative(&self) -> Result<Self, FrameError>

Alias for neg(). Matches np.negative(series).

Source

pub fn positive(&self) -> Result<Self, FrameError>

Element-wise identity (+x, no-op for numeric).

Matches np.positive(series) / +series.

Source

pub fn reverse(&self) -> Result<Self, FrameError>

Reverse the order of elements.

Matches series[::-1] / np.flip(series).

Source

pub fn flip(&self) -> Result<Self, FrameError>

Alias for reverse(). Matches np.flip(series).

Source

pub fn roll(&self, shift: i64) -> Result<Self, FrameError>

Roll elements along the axis by shift positions.

Matches np.roll(series, shift). Elements shifted off one end wrap around to the other.

Source

pub fn tile(&self, reps: usize) -> Result<Self, FrameError>

Tile (repeat) the series a given number of times.

Matches np.tile(series, reps).

Source

pub fn maximum(&self, other: &Self) -> Result<Self, FrameError>

Element-wise maximum of two Series.

Matches np.maximum(s1, s2). NaN propagates.

Source

pub fn minimum(&self, other: &Self) -> Result<Self, FrameError>

Element-wise minimum of two Series.

Matches np.minimum(s1, s2). NaN propagates.

Source

pub fn fmax(&self, other: &Self) -> Result<Self, FrameError>

Element-wise maximum ignoring NaN.

Matches np.fmax(s1, s2). Ignores NaN.

Source

pub fn fmin(&self, other: &Self) -> Result<Self, FrameError>

Element-wise minimum ignoring NaN.

Matches np.fmin(s1, s2). Ignores NaN.

Source

pub fn hypot(&self, other: &Self) -> Result<Self, FrameError>

Element-wise hypotenuse: sqrt(x2 + y2).

Matches np.hypot(s1, s2).

Source

pub fn atan2(&self, other: &Self) -> Result<Self, FrameError>

Element-wise arc tangent of y/x (choosing quadrant correctly).

Matches np.arctan2(y, x).

Source

pub fn arctan2(&self, other: &Self) -> Result<Self, FrameError>

Alias for atan2. Matches np.arctan2.

Source

pub fn copysign(&self, other: &Self) -> Result<Self, FrameError>

Element-wise copy sign from other to self.

Matches np.copysign(s1, s2).

Source

pub fn bitwise_and(&self, other: &Self) -> Result<Self, FrameError>

Element-wise bitwise AND.

Matches np.bitwise_and(s1, s2).

Source

pub fn bitwise_or(&self, other: &Self) -> Result<Self, FrameError>

Element-wise bitwise OR.

Matches np.bitwise_or(s1, s2).

Source

pub fn bitwise_xor(&self, other: &Self) -> Result<Self, FrameError>

Element-wise bitwise XOR.

Matches np.bitwise_xor(s1, s2).

Source

pub fn bitwise_not(&self) -> Result<Self, FrameError>

Element-wise bitwise NOT.

Matches np.bitwise_not(s) / np.invert(s).

Source

pub fn invert(&self) -> Result<Self, FrameError>

Alias for bitwise_not. Matches np.invert.

Source

pub fn float_power(&self, other: &Self) -> Result<Self, FrameError>

Element-wise float power.

Matches np.float_power(s1, s2).

Source

pub fn floor_divide(&self, other: &Self) -> Result<Self, FrameError>

Element-wise floor division.

Matches np.floor_divide(s1, s2) / s1 // s2.

Source

pub fn fmod(&self, other: &Self) -> Result<Self, FrameError>

Element-wise float modulo.

Matches np.fmod(s1, s2).

Source

pub fn power(&self, other: &Self) -> Result<Self, FrameError>

Element-wise power.

Matches np.power(s1, s2) / s1 ** s2.

Source

pub fn remainder(&self, other: &Self) -> Result<Self, FrameError>

Element-wise remainder.

Matches np.remainder(s1, s2) / s1 % s2.

Source

pub fn heaviside(&self, h0: f64) -> Result<Self, FrameError>

Heaviside step function.

Matches np.heaviside(s, h0). Returns 0 where x < 0, h0 where x == 0, 1 where x > 0.

Source

pub fn ldexp(&self, exp: i32) -> Result<Self, FrameError>

Multiply by 2^exp.

Matches np.ldexp(s, exp).

Source

pub fn logaddexp(&self, other: &Self) -> Result<Self, FrameError>

Log of sum of exponentials: log(exp(s1) + exp(s2)).

Matches np.logaddexp(s1, s2).

Source

pub fn logaddexp2(&self, other: &Self) -> Result<Self, FrameError>

Log base 2 of sum of exponentials: log2(2^s1 + 2^s2).

Matches np.logaddexp2(s1, s2).

Source

pub fn spacing(&self) -> Result<Self, FrameError>

Spacing to next representable float.

Matches np.spacing(s). Returns ULP (unit in last place) for each element.

Source

pub fn digitize(&self, bins: &Self, right: bool) -> Result<Self, FrameError>

Digitize: bin indices for each element.

Matches np.digitize(s, bins, right). Returns index of bin each element falls into.

Source

pub fn interpolate_linear(&self) -> Result<Self, FrameError>

Linear interpolation to fill missing values.

Matches pd.Series.interpolate(method='linear').

Source

pub fn gcd(&self, other: &Self) -> Result<Self, FrameError>

Element-wise greatest common divisor.

Matches np.gcd(s1, s2).

Source

pub fn gradient(&self) -> Result<Self, FrameError>

Numerical gradient (forward/central/backward differences).

Matches np.gradient(s).

Source

pub fn convolve(&self, kernel: &Self, mode: &str) -> Result<Self, FrameError>

Discrete convolution of the series with a kernel.

Matches np.convolve(s, kernel, mode). Mode: “full”, “same”, “valid”. Returns a Series with a RangeIndex matching the output length.

Source

pub fn correlate(&self, other: &Self, mode: &str) -> Result<Self, FrameError>

Cross-correlation of the series with another.

Matches np.correlate(s1, s2, mode). Mode: “full”, “same”, “valid”. Returns a Series with a RangeIndex matching the output length.

Source

pub fn compress(&self, condition: &Self) -> Result<Self, FrameError>

Compress series using a boolean condition.

Matches np.compress(condition, s). Returns elements where condition is true. Returns a Series with a RangeIndex matching the output length.

Source

pub fn bincount(&self, minlength: usize) -> Result<Self, FrameError>

Bin count for non-negative integer values.

Matches np.bincount(s, minlength). Returns counts for each integer bin.

Source

pub fn flatnonzero(&self) -> Result<Self, FrameError>

Indices of non-zero elements.

Matches np.flatnonzero(s). Returns indices where values are non-zero.

Source

pub fn fillna_with_series(&self, other: &Self) -> Result<Self, FrameError>

Fill null values using values from another series.

Matches pd.Series.fillna(other) when other is a Series.

Source

pub fn ediff1d( &self, to_begin: Option<Scalar>, to_end: Option<Scalar>, ) -> Result<Self, FrameError>

Differences between consecutive elements.

Matches np.ediff1d(s, to_begin, to_end). Prepends to_begin and appends to_end.

Source

pub fn cov_ddof(&self, other: &Self, ddof: usize) -> Scalar

Covariance with degrees of freedom adjustment.

Matches np.cov / pd.DataFrame.cov(ddof). Returns scalar covariance value.

Source

pub fn frexp(&self) -> Result<(Self, Self), FrameError>

Decompose float into mantissa and exponent.

Matches np.frexp(x). Returns (mantissa, exponent) where:

  • mantissa is in [0.5, 1.0) or exactly 0.0
  • exponent is an integer
  • x = mantissa * 2^exponent
Source

pub fn histogram(&self, bin_edges: &[f64]) -> Result<Self, FrameError>

Compute histogram using provided bin edges.

Matches np.histogram(a, bins=edges). Returns counts for each bin. Bins are [edges[i], edges[i+1]) except the last which is [edges[n-1], edges[n]].

Source

pub fn histogram_auto( &self, n_bins: usize, ) -> Result<(Self, Vec<f64>), FrameError>

Compute histogram with auto-generated bins.

Matches np.histogram(a, bins=n_bins). Returns (counts, bin_edges). Bins are evenly spaced between min and max of the data.

Source

pub fn hist_counts(&self, bins: usize) -> Vec<usize>

Compute histogram counts.

Matches the bins=n histogram path behind pd.Series.hist.

Source

pub fn argpartition(&self, kth: usize) -> Result<Vec<usize>, FrameError>

Return indices that partition the array around kth element.

Matches np.argpartition(). After partition, element at kth position is in its sorted position, elements before are <= kth element, elements after are >= kth element.

Source

pub fn partition(&self, kth: usize) -> Result<Self, FrameError>

Partition array around kth smallest element.

Matches np.partition(). Returns a partially sorted Series where element at kth position is in its final sorted position.

Source

pub fn array_split(&self, n: usize) -> Result<Vec<Self>, FrameError>

Split Series into n equal-ish parts.

Matches np.array_split(). Returns Vec of Series.

Source

pub fn split(&self, n: usize) -> Result<Vec<Self>, FrameError>

Alias for array_split.

Source

pub fn zeros_like(&self) -> Result<Self, FrameError>

Create a zeros Series with same shape and dtype as self.

Matches np.zeros_like().

Source

pub fn ones_like(&self) -> Result<Self, FrameError>

Create a ones Series with same shape and dtype as self.

Matches np.ones_like().

Source

pub fn full_like(&self, fill_value: Scalar) -> Result<Self, FrameError>

Create a Series filled with fill_value with same shape as self.

Matches np.full_like().

Source

pub fn logical_and(&self, other: &Self) -> Result<Self, FrameError>

Logical AND between two Series.

Matches np.logical_and().

Source

pub fn logical_or(&self, other: &Self) -> Result<Self, FrameError>

Logical OR between two Series.

Matches np.logical_or().

Source

pub fn logical_xor(&self, other: &Self) -> Result<Self, FrameError>

Logical XOR between two Series.

Matches np.logical_xor().

Source

pub fn logical_not(&self) -> Result<Self, FrameError>

Logical NOT (element-wise negation to boolean).

Matches np.logical_not().

Source

pub fn left_shift(&self, other: &Self) -> Result<Self, FrameError>

Left bit shift.

Matches np.left_shift().

Source

pub fn modf(&self) -> Result<(Self, Self), FrameError>

Split into integer and fractional parts.

Matches np.modf(x). Returns (fractional_part, integer_part) as two Series.

Source

pub fn sum(&self) -> Result<Scalar, FrameError>

Sum of non-null numeric values. Returns Scalar::Float64(0.0) for empty.

Matches pd.Series.sum().

Source

pub fn mean(&self) -> Result<Scalar, FrameError>

Mean of non-null numeric values. Returns NaN for empty.

Matches pd.Series.mean().

Source

pub fn average(&self, weights: &Self) -> Scalar

Weighted average of non-null numeric values.

Matches np.average(s, weights=w). Returns NaN if all weights are zero or the series is empty.

Source

pub fn min(&self) -> Result<Scalar, FrameError>

Min of non-null numeric values. Returns NaN for empty.

Matches pd.Series.min().

Source

pub fn max(&self) -> Result<Scalar, FrameError>

Max of non-null numeric values. Returns NaN for empty.

Matches pd.Series.max().

Source

pub fn std(&self) -> Result<Scalar, FrameError>

Standard deviation of non-null numeric values (ddof=1, sample std).

Matches pd.Series.std().

Source

pub fn var(&self) -> Result<Scalar, FrameError>

Variance of non-null numeric values (ddof=1, sample variance).

Matches pd.Series.var().

Source

pub fn var_ddof(&self, ddof: usize) -> Result<Scalar, FrameError>

Variance with configurable degrees of freedom.

Matches pd.Series.var(ddof=n). ddof=0 gives population variance, ddof=1 (default in pandas) gives sample variance.

Source

pub fn std_ddof(&self, ddof: usize) -> Result<Scalar, FrameError>

Standard deviation with configurable degrees of freedom.

Matches pd.Series.std(ddof=n).

Source

pub fn median(&self) -> Result<Scalar, FrameError>

Median of non-null numeric values. Returns NaN for empty.

Matches pd.Series.median().

Source

pub fn any(&self) -> Result<bool, FrameError>

Whether any non-missing value is truthy.

Matches pd.Series.any() with default skipna=True.

Source

pub fn all(&self) -> Result<bool, FrameError>

Whether all non-missing values are truthy.

Matches pd.Series.all() with default skipna=True.

Source

pub fn prod(&self) -> Result<Scalar, FrameError>

Product of non-null numeric values. Returns 1.0 for empty.

Matches pd.Series.prod().

Source

pub fn product(&self) -> Result<Scalar, FrameError>

pandas alias for Self::prod. Matches pd.Series.product(). Per br-frankenpandas-az1pt.

Source

pub fn sum_skipna(&self, skipna: bool) -> Result<Scalar, FrameError>

Sum with skipna control.

Matches pd.Series.sum(skipna=True|False). When skipna=False, returns NaN if any value is missing.

Source

pub fn mean_skipna(&self, skipna: bool) -> Result<Scalar, FrameError>

Mean with skipna control.

Source

pub fn min_skipna(&self, skipna: bool) -> Result<Scalar, FrameError>

Min with skipna control.

Source

pub fn max_skipna(&self, skipna: bool) -> Result<Scalar, FrameError>

Max with skipna control.

Source

pub fn std_skipna(&self, skipna: bool) -> Result<Scalar, FrameError>

Std with skipna control.

Source

pub fn var_skipna(&self, skipna: bool) -> Result<Scalar, FrameError>

Var with skipna control.

Source

pub fn median_skipna(&self, skipna: bool) -> Result<Scalar, FrameError>

Median with skipna control.

Source

pub fn prod_skipna(&self, skipna: bool) -> Result<Scalar, FrameError>

Prod with skipna control.

Source

pub fn nansum(&self) -> Result<Scalar, FrameError>

Alias for sum, matching np.nansum.

Source

pub fn nanmean(&self) -> Result<Scalar, FrameError>

Alias for mean, matching np.nanmean.

Source

pub fn nanmin(&self) -> Result<Scalar, FrameError>

Alias for min, matching np.nanmin.

Source

pub fn nanmax(&self) -> Result<Scalar, FrameError>

Alias for max, matching np.nanmax.

Source

pub fn nanprod(&self) -> Result<Scalar, FrameError>

Alias for prod, matching np.nanprod.

Source

pub fn nanstd(&self, ddof: usize) -> Result<Scalar, FrameError>

Alias for std_ddof, matching np.nanstd.

Source

pub fn nanvar(&self, ddof: usize) -> Result<Scalar, FrameError>

Alias for var_ddof, matching np.nanvar.

Source

pub fn nanmedian(&self) -> Result<Scalar, FrameError>

Alias for median, matching np.nanmedian.

Source

pub fn lcm(&self, other: &Self) -> Result<Self, FrameError>

Element-wise least common multiple.

Matches np.lcm(x, y).

Source

pub fn ptp(&self) -> Scalar

Peak-to-peak range (max − min) over non-missing values.

Matches np.ptp.

Source

pub fn nonzero(&self) -> Vec<usize>

Indices of non-zero/truthy elements.

Matches np.nonzero().

Source

pub fn nextafter(&self, other: &Self) -> Result<Self, FrameError>

Return the next representable floating-point value after x toward y.

Matches np.nextafter(x, y).

Source

pub fn percentile(&self, p: f64) -> Scalar

Percentile of non-missing values.

Matches np.percentile(). Takes percentile p in [0, 100].

Source

pub fn nanquantile(&self, q: f64) -> Result<Scalar, FrameError>

Alias for quantile, matching np.nanquantile.

Source

pub fn nanpercentile(&self, p: f64) -> Scalar

Alias for percentile, matching np.nanpercentile.

Source

pub fn put( &self, indices: &[usize], values: &[Scalar], ) -> Result<Self, FrameError>

Replace elements at specified indices with given values.

Matches np.put(). Returns a new Series with values replaced at indices.

Source

pub fn sinc(&self) -> Result<Self, FrameError>

Compute the sinc function.

Matches np.sinc(x). Returns sin(pi*x) / (pi*x), with sinc(0) = 1.

Source

pub fn trapz(&self, dx: f64) -> Result<Scalar, FrameError>

Trapezoidal numerical integration.

Matches np.trapz(). Returns scalar result of integral.

Source

pub fn trim_zeros(&self, trim: &str) -> Result<Self, FrameError>

Trim leading and/or trailing zeros.

Matches np.trim_zeros(). The trim parameter specifies:

  • "f": trim leading zeros
  • "b": trim trailing zeros
  • "fb" (default): trim both
Source

pub fn weighted_mean(&self, weights: &Self) -> Scalar

Weighted average of non-missing values.

Matches np.average(a, weights=w). Returns NaN if weights sum to zero.

Source

pub fn resize(&self, new_size: usize) -> Result<Self, FrameError>

Resize Series to new size, padding or truncating as needed.

Matches np.resize(). If new size is larger, values cycle from beginning.

Source

pub fn true_divide(&self, other: &Self) -> Result<Self, FrameError>

Alias for div, matching NumPy naming.

Source

pub fn right_shift(&self, other: &Self) -> Result<Self, FrameError>

Right bit shift.

Matches np.right_shift().

Source

pub fn diff_valid(&self) -> Result<Self, FrameError>

Difference computed only over valid (non-missing) values.

Matches the pandas idiom s.dropna().diff().reindex(s.index). Missing values propagate; the first valid value yields NaN.

Source

pub fn nanargmin(&self) -> Result<i64, FrameError>

Alias for argmin, matching np.nanargmin.

Source

pub fn nanargmax(&self) -> Result<i64, FrameError>

Alias for argmax, matching np.nanargmax.

Source

pub fn nan_to_num_with_values( &self, nan: f64, posinf: f64, neginf: f64, ) -> Result<Self, FrameError>

Replace NaN and infinity with specified values.

Matches np.nan_to_num(x, nan=nan, posinf=posinf, neginf=neginf).

Source

pub fn isclose( &self, other: &Self, rtol: f64, atol: f64, ) -> Result<Self, FrameError>

Element-wise comparison for approximate equality.

Matches np.isclose(). Returns True where |a - b| <= atol + rtol * |b|.

Source

pub fn mode(&self) -> Result<Self, FrameError>

Most frequently occurring value(s).

Matches pd.Series.mode(). Returns a new Series containing all values tied for the highest frequency, sorted ascending.

Source

pub fn mode_with_dropna(&self, dropna: bool) -> Result<Self, FrameError>

Most frequently occurring value(s) with explicit null counting control.

Matches pd.Series.mode(dropna=...).

Source

pub fn shift(&self, periods: i64) -> Result<Self, FrameError>

Shift values by periods positions, filling with NaN.

Matches pd.Series.shift(periods). Positive shifts move values downward (earlier positions become NaN); negative shifts move values upward (later positions become NaN).

Source

pub fn diff(&self, periods: i64) -> Result<Self, FrameError>

Element-wise difference with the previous element.

Matches pd.Series.diff(periods). Computes value[i] - value[i - periods]. Produces NaN for positions without a valid predecessor and for nulls.

Source

pub fn cumsum(&self) -> Result<Self, FrameError>

Cumulative sum, skipping NaN.

Matches pd.Series.cumsum(skipna=True).

Source

pub fn cumprod(&self) -> Result<Self, FrameError>

Cumulative product, skipping NaN.

Matches pd.Series.cumprod(skipna=True).

Source

pub fn cummin(&self) -> Result<Self, FrameError>

Cumulative minimum, skipping NaN.

Matches pd.Series.cummin(skipna=True).

Source

pub fn cummax(&self) -> Result<Self, FrameError>

Cumulative maximum, skipping NaN.

Matches pd.Series.cummax(skipna=True).

Source

pub fn where_cond( &self, cond: &Self, other: Option<&Scalar>, ) -> Result<Self, FrameError>

Keep values where cond is True; replace others with other.

Matches series.where(cond, other). If other is None, replaced values become NaN. The condition Series is aligned to self via left-index alignment before masking.

Source

pub fn where( &self, cond: &Self, other: Option<&Scalar>, ) -> Result<Self, FrameError>

Pandas-named alias for Self::where_cond.

Matches pd.Series.where(cond, other). Raw identifier syntax keeps the pandas spelling available despite Rust’s where keyword.

Source

pub fn where_cond_series( &self, cond: &Self, other: &Self, ) -> Result<Self, FrameError>

Keep values where cond is True, replacing False positions with corresponding values from other Series.

Matches series.where(cond, other=series).

Source

pub fn where_series( &self, cond: &Self, other: &Self, ) -> Result<Self, FrameError>

Pandas-named Series replacement alias for Self::where_cond_series.

Source

pub fn mask_series(&self, cond: &Self, other: &Self) -> Result<Self, FrameError>

Replace values where cond is True with corresponding values from other Series.

Matches series.mask(cond, other=series).

Source

pub fn mask( &self, cond: &Self, other: Option<&Scalar>, ) -> Result<Self, FrameError>

Replace values where cond is True with other.

Matches series.mask(cond, other). This is the inverse of where: values are replaced where the condition IS True, not where it is False.

Source

pub fn isin(&self, test_values: &[Scalar]) -> Result<Self, FrameError>

Source

pub fn between( &self, left: &Scalar, right: &Scalar, inclusive: &str, ) -> Result<Self, FrameError>

Test whether each element falls within a range.

Matches series.between(left, right, inclusive='both'). Returns a boolean Series. The inclusive parameter controls boundary behavior:

  • "both": left <= x <= right
  • "neither": left < x < right
  • "left": left <= x < right
  • "right": left < x <= right

Null elements produce false.

Source

pub fn idxmin(&self) -> Result<IndexLabel, FrameError>

Return the label of the minimum value.

Matches series.idxmin(). Skips missing values. Returns an error if the series is empty or all-null.

Source

pub fn idxmax(&self) -> Result<IndexLabel, FrameError>

Return the label of the maximum value.

Matches series.idxmax(). Skips missing values.

Source

pub fn nlargest(&self, n: usize) -> Result<Self, FrameError>

Return the n largest values as a new Series, sorted descending.

Matches series.nlargest(n). Missing values are excluded.

Source

pub fn nsmallest(&self, n: usize) -> Result<Self, FrameError>

Return the n smallest values as a new Series, sorted ascending.

Matches series.nsmallest(n). Missing values are excluded.

Source

pub fn nsmallest_keep(&self, n: usize, keep: &str) -> Result<Self, FrameError>

Return the n smallest values with keep parameter.

Matches series.nsmallest(n, keep='first'|'last'|'all').

  • first: keep first occurrence of duplicates
  • last: keep last occurrence of duplicates
  • all: keep all occurrences (may return more than n rows)
Source

pub fn nlargest_keep(&self, n: usize, keep: &str) -> Result<Self, FrameError>

Return the n largest values with keep parameter.

Matches series.nlargest(n, keep='first'|'last'|'all').

Source

pub fn argsort(&self, ascending: bool) -> Result<Self, FrameError>

Return the integer indices that would sort the Series.

Matches pd.Series.argsort() for the default ascending path.

Current pandas maps missing positions to -1; descending argsort is a FrankenPandas extension and keeps missing values last.

Source

pub fn argmin(&self) -> Result<i64, FrameError>

Return the integer position of the minimum value.

Matches pd.Series.argmin(). Skips missing values.

Source

pub fn argmin_skipna(&self, skipna: bool) -> Result<i64, FrameError>

Return the integer position of the minimum value with explicit NA handling.

Matches pd.Series.argmin(skipna=...). Current pandas returns -1 for all-NA inputs and for skipna=false inputs containing any NA.

Source

pub fn argmax(&self) -> Result<i64, FrameError>

Return the integer position of the maximum value.

Matches pd.Series.argmax(). Skips missing values.

Source

pub fn argmax_skipna(&self, skipna: bool) -> Result<i64, FrameError>

Return the integer position of the maximum value with explicit NA handling.

Matches pd.Series.argmax(skipna=...). Current pandas returns -1 for all-NA inputs and for skipna=false inputs containing any NA.

Source

pub fn take(&self, indices: &[i64]) -> Result<Self, FrameError>

Select elements by integer positions.

Matches pd.Series.take(indices), including negative indices from the end.

Examples found in repository?
examples/bench_take_gather.rs (line 32)
27fn golden() -> String {
28    let mut out = String::new();
29
30    // Series::take across dtypes, negative + duplicate indices.
31    let s = s_i64(vec![10, 20, 30, 40, 50]);
32    let r = s.take(&[4, 0, -1, 2, -5, 2]).unwrap();
33    out.push_str(&format!("take_lbls={:?}\n", r.index().labels()));
34    out.push_str(&format!("take_vals={:?}\n", r.values()));
35    out.push_str(&format!("take_oob_err={}\n", s.take(&[99]).is_err()));
36
37    let f = s_scalars(vec![
38        Scalar::Float64(1.5),
39        Scalar::Float64(f64::NAN),
40        Scalar::Float64(-3.0),
41    ]);
42    out.push_str(&format!(
43        "take_f64={:?}\n",
44        f.take(&[2, 1, 0]).unwrap().values()
45    ));
46    let ni = s_scalars(vec![
47        Scalar::Int64(7),
48        Scalar::Null(NullKind::NaN),
49        Scalar::Int64(9),
50    ]);
51    out.push_str(&format!(
52        "take_ni={:?}\n",
53        ni.take(&[1, 2, 0]).unwrap().values()
54    ));
55    let u = s_scalars(
56        vec!["a", "b", "c"]
57            .into_iter()
58            .map(|x| Scalar::Utf8(x.into()))
59            .collect(),
60    );
61    out.push_str(&format!(
62        "take_utf8={:?}\n",
63        u.take(&[2, -3]).unwrap().values()
64    ));
65
66    // SeriesGroupBy gather paths (nlargest / head) route through take_positions.
67    let data = s_i64(vec![5, 1, 9, 3, 7, 2, 8]);
68    let keys = s_scalars(
69        vec!["a", "b", "a", "b", "a", "b", "a"]
70            .into_iter()
71            .map(|x| Scalar::Utf8(x.into()))
72            .collect(),
73    );
74    let gb = data.groupby(&keys).unwrap();
75    let nl = gb.nlargest(2).unwrap();
76    out.push_str(&format!("gb_nlargest_lbls={:?}\n", nl.index().labels()));
77    out.push_str(&format!("gb_nlargest_vals={:?}\n", nl.values()));
78    let hd = data.groupby(&keys).unwrap().head(1).unwrap();
79    out.push_str(&format!("gb_head_vals={:?}\n", hd.values()));
80    out
81}
82
83fn main() {
84    let g = golden();
85    print!("GOLDEN_BEGIN\n{g}GOLDEN_END\n");
86
87    let n: usize = 1_000_000;
88    let s = s_i64((0..n as i64).map(|v| v * 2).collect());
89    let mut x: u64 = 0xfeed_face;
90    let idxs: Vec<i64> = (0..n)
91        .map(|_| {
92            x = x
93                .wrapping_mul(6364136223846793005)
94                .wrapping_add(1442695040888963407);
95            (x >> 16) as i64 % (n as i64)
96        })
97        .collect();
98
99    let _ = s.take(&idxs).unwrap(); // warmup
100
101    let t = Instant::now();
102    let r = s.take(&idxs).unwrap();
103    let d = t.elapsed();
104    assert_eq!(r.len(), n);
105
106    println!("TIMING n={n} take={:.3}ms", d.as_secs_f64() * 1e3);
107}
Source

pub fn searchsorted( &self, value: &Scalar, side: &str, ) -> Result<usize, FrameError>

Find insertion points to maintain sorted order.

Matches pd.Series.searchsorted(value, side='left'|'right'). The Series must be sorted. Returns integer positions.

Works for any ordered Scalar type — numeric (Int64/Float64/ Timedelta64), textual (Utf8), and Bool. Previously the implementation coerced the needle to f64 unconditionally, which rejected Utf8 needles with a non-numeric type error even though pandas supports string searchsorted on string-sorted Series.

Examples found in repository?
examples/bench_searchsorted.rs (line 105)
29fn golden() -> String {
30    let mut out = String::new();
31
32    // Sorted Int64, both sides, exact + between + below + above.
33    let s = s_i64(vec![10, 20, 20, 30, 40]);
34    let needles: Vec<Scalar> = vec![5, 10, 15, 20, 35, 40, 50]
35        .into_iter()
36        .map(Scalar::Int64)
37        .collect();
38    out.push_str(&format!(
39        "i64_left={:?}\n",
40        s.searchsorted_values(&needles, "left").unwrap()
41    ));
42    out.push_str(&format!(
43        "i64_right={:?}\n",
44        s.searchsorted_values(&needles, "right").unwrap()
45    ));
46
47    // Sorted Float64 with trailing missing (NaN sorts last).
48    let fs = s_scalars(vec![
49        Scalar::Float64(1.5),
50        Scalar::Float64(2.5),
51        Scalar::Float64(2.5),
52        Scalar::Float64(9.0),
53        Scalar::Float64(f64::NAN),
54    ]);
55    let fn_needles = vec![
56        Scalar::Float64(2.5),
57        Scalar::Float64(0.0),
58        Scalar::Float64(10.0),
59        Scalar::Float64(f64::NAN), // missing needle
60    ];
61    out.push_str(&format!(
62        "f64_left={:?}\n",
63        fs.searchsorted_values(&fn_needles, "left").unwrap()
64    ));
65    out.push_str(&format!(
66        "f64_right={:?}\n",
67        fs.searchsorted_values(&fn_needles, "right").unwrap()
68    ));
69
70    // Sorted Utf8.
71    let us = s_scalars(
72        vec!["apple", "banana", "banana", "cherry"]
73            .into_iter()
74            .map(|x| Scalar::Utf8(x.to_string()))
75            .collect(),
76    );
77    let u_needles: Vec<Scalar> = vec!["aardvark", "banana", "date"]
78        .into_iter()
79        .map(|x| Scalar::Utf8(x.to_string()))
80        .collect();
81    out.push_str(&format!(
82        "utf8_left={:?}\n",
83        us.searchsorted_values(&u_needles, "left").unwrap()
84    ));
85    out.push_str(&format!(
86        "utf8_right={:?}\n",
87        us.searchsorted_values(&u_needles, "right").unwrap()
88    ));
89
90    // UNSORTED input: must fall back to the exact linear-scan behavior.
91    let uns = s_i64(vec![30, 10, 40, 20, 20]);
92    let un_needles: Vec<Scalar> = vec![5, 20, 35, 40].into_iter().map(Scalar::Int64).collect();
93    out.push_str(&format!(
94        "unsorted_left={:?}\n",
95        uns.searchsorted_values(&un_needles, "left").unwrap()
96    ));
97    out.push_str(&format!(
98        "unsorted_right={:?}\n",
99        uns.searchsorted_values(&un_needles, "right").unwrap()
100    ));
101
102    // Single-value searchsorted unchanged.
103    out.push_str(&format!(
104        "single_left={}\n",
105        s.searchsorted(&Scalar::Int64(20), "left").unwrap()
106    ));
107    out.push_str(&format!(
108        "single_right={}\n",
109        s.searchsorted(&Scalar::Int64(20), "right").unwrap()
110    ));
111    out.push_str(&format!(
112        "single_missing_left={}\n",
113        fs.searchsorted(&Scalar::Float64(f64::NAN), "left").unwrap()
114    ));
115    out.push_str(&format!(
116        "single_missing_right={}\n",
117        fs.searchsorted(&Scalar::Float64(f64::NAN), "right")
118            .unwrap()
119    ));
120
121    out
122}
Source

pub fn searchsorted_values( &self, values: &[Scalar], side: &str, ) -> Result<Vec<usize>, FrameError>

Find insertion points for array-like values to maintain sorted order.

Matches pd.Series.searchsorted(values, side='left'|'right') for array-like inputs. The Series must be sorted. Returns integer positions in the same order as the input slice.

Examples found in repository?
examples/bench_searchsorted.rs (line 40)
29fn golden() -> String {
30    let mut out = String::new();
31
32    // Sorted Int64, both sides, exact + between + below + above.
33    let s = s_i64(vec![10, 20, 20, 30, 40]);
34    let needles: Vec<Scalar> = vec![5, 10, 15, 20, 35, 40, 50]
35        .into_iter()
36        .map(Scalar::Int64)
37        .collect();
38    out.push_str(&format!(
39        "i64_left={:?}\n",
40        s.searchsorted_values(&needles, "left").unwrap()
41    ));
42    out.push_str(&format!(
43        "i64_right={:?}\n",
44        s.searchsorted_values(&needles, "right").unwrap()
45    ));
46
47    // Sorted Float64 with trailing missing (NaN sorts last).
48    let fs = s_scalars(vec![
49        Scalar::Float64(1.5),
50        Scalar::Float64(2.5),
51        Scalar::Float64(2.5),
52        Scalar::Float64(9.0),
53        Scalar::Float64(f64::NAN),
54    ]);
55    let fn_needles = vec![
56        Scalar::Float64(2.5),
57        Scalar::Float64(0.0),
58        Scalar::Float64(10.0),
59        Scalar::Float64(f64::NAN), // missing needle
60    ];
61    out.push_str(&format!(
62        "f64_left={:?}\n",
63        fs.searchsorted_values(&fn_needles, "left").unwrap()
64    ));
65    out.push_str(&format!(
66        "f64_right={:?}\n",
67        fs.searchsorted_values(&fn_needles, "right").unwrap()
68    ));
69
70    // Sorted Utf8.
71    let us = s_scalars(
72        vec!["apple", "banana", "banana", "cherry"]
73            .into_iter()
74            .map(|x| Scalar::Utf8(x.to_string()))
75            .collect(),
76    );
77    let u_needles: Vec<Scalar> = vec!["aardvark", "banana", "date"]
78        .into_iter()
79        .map(|x| Scalar::Utf8(x.to_string()))
80        .collect();
81    out.push_str(&format!(
82        "utf8_left={:?}\n",
83        us.searchsorted_values(&u_needles, "left").unwrap()
84    ));
85    out.push_str(&format!(
86        "utf8_right={:?}\n",
87        us.searchsorted_values(&u_needles, "right").unwrap()
88    ));
89
90    // UNSORTED input: must fall back to the exact linear-scan behavior.
91    let uns = s_i64(vec![30, 10, 40, 20, 20]);
92    let un_needles: Vec<Scalar> = vec![5, 20, 35, 40].into_iter().map(Scalar::Int64).collect();
93    out.push_str(&format!(
94        "unsorted_left={:?}\n",
95        uns.searchsorted_values(&un_needles, "left").unwrap()
96    ));
97    out.push_str(&format!(
98        "unsorted_right={:?}\n",
99        uns.searchsorted_values(&un_needles, "right").unwrap()
100    ));
101
102    // Single-value searchsorted unchanged.
103    out.push_str(&format!(
104        "single_left={}\n",
105        s.searchsorted(&Scalar::Int64(20), "left").unwrap()
106    ));
107    out.push_str(&format!(
108        "single_right={}\n",
109        s.searchsorted(&Scalar::Int64(20), "right").unwrap()
110    ));
111    out.push_str(&format!(
112        "single_missing_left={}\n",
113        fs.searchsorted(&Scalar::Float64(f64::NAN), "left").unwrap()
114    ));
115    out.push_str(&format!(
116        "single_missing_right={}\n",
117        fs.searchsorted(&Scalar::Float64(f64::NAN), "right")
118            .unwrap()
119    ));
120
121    out
122}
123
124fn main() {
125    let g = golden();
126    print!("GOLDEN_BEGIN\n{g}GOLDEN_END\n");
127
128    let n: usize = 40_000;
129    let m: usize = 40_000;
130    let s = s_i64((0..n as i64).map(|v| v * 2).collect());
131    let needles: Vec<Scalar> = (0..m as i64).map(|v| Scalar::Int64(v * 2 + 1)).collect();
132
133    // warmup
134    let _ = s.searchsorted_values(&needles, "left").unwrap();
135
136    let t = Instant::now();
137    let r = s.searchsorted_values(&needles, "left").unwrap();
138    let d = t.elapsed();
139    assert_eq!(r.len(), m);
140
141    println!(
142        "TIMING n={n} m={m} searchsorted_values={:.3}ms",
143        d.as_secs_f64() * 1e3
144    );
145}
Source

pub fn searchsorted_with_sorter( &self, value: &Scalar, side: &str, sorter: &[i64], ) -> Result<usize, FrameError>

Find an insertion point using an explicit sorter permutation.

Matches pd.Series.searchsorted(value, side='left'|'right', sorter=...). sorter must have the same length as the Series and describe the integer positions that would sort the Series.

Source

pub fn searchsorted_values_with_sorter( &self, values: &[Scalar], side: &str, sorter: &[i64], ) -> Result<Vec<usize>, FrameError>

Find insertion points for array-like values using an explicit sorter.

Matches pd.Series.searchsorted(values, side='left'|'right', sorter=...).

Source

pub fn factorize_with_options( &self, sort: bool, use_na_sentinel: bool, ) -> Result<(Self, Self), FrameError>

Encode the Series as an enumerated type.

Matches pd.Series.factorize(). Returns (codes, uniques) where codes is an Int64 Series of category indices (-1 for NaN) and uniques is a Series of the unique values in order of appearance. Factorize with sort + use_na_sentinel options.

Per br-frankenpandas-ca5bc2: matches pd.Series.factorize(sort, use_na_sentinel).

  • sort=true: uniques are returned in sorted order; codes are remapped accordingly.
  • use_na_sentinel=false: missing values become a regular unique bucket with their own code instead of -1.

Delegates to fp-columnar’s Column::factorize_with_options (br-9433f).

Source

pub fn factorize(&self) -> Result<(Self, Self), FrameError>

Source

pub fn sample( &self, n: Option<usize>, frac: Option<f64>, replace: bool, seed: Option<u64>, ) -> Result<Self, FrameError>

Randomly sample elements from the Series.

Matches pd.Series.sample(n, frac, replace, random_state).

Source

pub fn sem(&self) -> Result<f64, FrameError>

Standard error of the mean.

Matches pd.Series.sem(). Computes std / sqrt(n).

Source

pub fn skew(&self) -> Result<f64, FrameError>

Skewness (Fisher’s definition, bias=False).

Matches pd.Series.skew().

Source

pub fn kurtosis(&self) -> Result<f64, FrameError>

Excess kurtosis (Fisher’s definition, bias=False).

Matches pd.Series.kurtosis() / pd.Series.kurt().

Source

pub fn kurt(&self) -> Result<f64, FrameError>

Alias for kurtosis().

Source

pub fn squeeze(&self) -> Result<Scalar, Box<Self>>

Squeeze a single-element Series to a Scalar.

Matches pd.Series.squeeze(). Returns the single value if length is 1, otherwise returns self unchanged wrapped in Err.

Source

pub fn item(&self) -> Result<Scalar, FrameError>

Extract scalar value from a single-element Series.

Matches pd.Series.item(). Returns an error if the Series does not have exactly one element.

Source

pub fn repeat(&self, repeats: usize) -> Result<Self, FrameError>

Repeat each element a constant number of times.

Matches the scalar repeats form of pd.Series.repeat(repeats).

Source

pub fn repeat_by(&self, repeats: &[usize]) -> Result<Self, FrameError>

Repeat each element according to the corresponding repeat count.

Matches the array-like repeats form of pd.Series.repeat(repeats).

Source

pub fn bool_(&self) -> Result<bool, FrameError>

Extract the single boolean value from a single-element Series.

Matches pd.Series.bool(). Raises an error unless the Series has exactly one element and that element is a boolean scalar.

Source

pub fn memory_usage(&self) -> usize

Approximate memory usage in bytes.

Matches pd.Series.memory_usage(). Includes index and values.

Source

pub fn hasnans(&self) -> bool

Return true if the Series contains any NaN or null values.

Matches pd.Series.hasnans.

Source

pub fn nbytes(&self) -> usize

Return the approximate number of bytes used by the Series values.

Matches pd.Series.nbytes. Does not include the index.

Source

pub fn ndim(&self) -> usize

Number of axes — always 1 for Series.

Matches pd.Series.ndim.

Source

pub fn size(&self) -> usize

Number of elements in the Series.

Matches pd.Series.size. Equivalent to len() but follows the pandas property naming so callers can write size-generic code that works on both Series and DataFrame.

Source

pub fn shape(&self) -> (usize,)

Shape of the Series.

Matches pd.Series.shape as a one-element tuple.

Source

pub fn axes(&self) -> Vec<Vec<IndexLabel>>

Axes of the Series — a single-entry Vec containing the index labels (pandas returns [self.index]).

Matches pd.Series.axes.

Source

pub fn empty(&self) -> bool

Whether the Series has zero elements.

Matches pd.Series.empty.

Source

pub fn attrs(&self) -> BTreeMap<String, Scalar>

User metadata mapping.

Matches pd.Series.attrs shape. FrankenPandas does not yet persist mutable attrs on the Series storage object, so the current accessor returns the default empty metadata map.

Source

pub fn info(&self) -> String

Human-readable Series summary.

Matches pd.Series.info() at the API-shape level for the current scalar-backed Series model.

Source

pub fn flags(&self) -> DataFrameFlags

Series flags metadata.

Matches pd.Series.flags for the duplicate-label flag currently represented by FrankenPandas.

Source

pub fn set_flags( &self, allows_duplicate_labels: Option<bool>, ) -> Result<Self, FrameError>

Return a Series with updated flags.

Matches pd.Series.set_flags(allows_duplicate_labels=...) for the duplicate-label flag.

Source

pub fn reset_index( &self, drop: bool, ) -> Result<SeriesResetIndexResult, FrameError>

Reset the Series index to a default RangeIndex.

Matches pd.Series.reset_index(drop=...):

  • drop=true: keep only the values; replace the index with 0..len and return a Series.
  • drop=false: widen to a two-column DataFrame with the materialized index first and the value column second.
Source

pub fn reset_index_with_name( &self, drop: bool, name: Option<&str>, ) -> Result<SeriesResetIndexResult, FrameError>

Matches pd.Series.reset_index(drop=..., name=...) for the single-index Series model.

Source

pub fn pipe<F>(&self, func: F) -> Result<Self, FrameError>
where F: FnOnce(&Self) -> Result<Self, FrameError>,

Pass the Series through a function.

Matches pd.Series.pipe(func). Useful for method chaining.

Source

pub fn items(&self) -> Vec<(IndexLabel, Scalar)>

Return an iterator over (index_label, value) pairs.

Matches pd.Series.items().

Source

pub fn iteritems(&self) -> Vec<(IndexLabel, Scalar)>

👎Deprecated:

use items() instead

Alias for items (deprecated in pandas but kept for compatibility).

Source

pub fn iat(&self, pos: i64) -> Result<Scalar, FrameError>

Access a scalar value by integer position.

Matches pd.Series.iat[i].

Source

pub fn at(&self, label: &IndexLabel) -> Result<Scalar, FrameError>

Access a scalar value by label.

Matches pd.Series.at[label].

Source

pub fn get(&self, label: &IndexLabel) -> Option<Scalar>

Dict-like scalar lookup by label.

Matches pd.Series.get(key) by returning None instead of an error for a missing label.

Source

pub fn get_or(&self, label: &IndexLabel, default: Scalar) -> Scalar

Dict-like scalar lookup with a fallback value.

Matches pd.Series.get(key, default=...).

Source

pub fn pop(&self, label: &IndexLabel) -> Result<(Scalar, Self), FrameError>

Return a value and a Series with its first matching label removed.

Matches pd.Series.pop(item) in an immutable form.

Source

pub fn transform<F>(&self, func: F) -> Result<Self, FrameError>
where F: Fn(&Scalar) -> Scalar,

Apply a function element-wise, returning a Series of the same shape.

Matches pd.Series.transform(func).

Source

pub fn pct_change(&self, periods: usize) -> Result<Self, FrameError>

Percentage change between current and prior element.

Matches series.pct_change(periods=1). pandas 2.2.3 applies the default fill_method='pad' (forward-fill) BEFORE computing — so an interior missing value uses the last valid observation, e.g. [1.0, nan, 4.0].pct_change() is [NaN, 0.0, 3.0], not all-NaN. (br-frankenpandas-5ioai) Use [pct_change_with_fill] with fill_method=None for the no-fill variant.

Source

pub fn pct_change_with_fill( &self, periods: usize, fill_method: Option<&str>, limit: Option<usize>, ) -> Result<Self, FrameError>

Percentage change with optional null fill before computation.

Matches series.pct_change(periods, fill_method=..., limit=...). fill_method is "ffill" / "pad" (forward-fill missing values, the pandas 2.2.3 default used by [pct_change]), "bfill" / "backfill" (backward-fill), or None (no fill — interior NaN propagates). limit caps consecutive fills; it is ignored when fill_method is None.

Source

pub fn to_frame(&self, name: Option<&str>) -> Result<DataFrame, FrameError>

Convert Series to a single-column DataFrame.

Matches series.to_frame(name=None). Uses the series name as the column name by default.

Source

pub fn asfreq(&self, freq: &str) -> Result<Self, FrameError>

Conform the index to a datetime frequency.

Matches pd.Series.asfreq(freq) for datetime-like indexes. Missing rows introduced by the new frequency are filled with NaN.

Source

pub fn asfreq_with_options( &self, freq: &str, method: Option<&str>, fill_value: Option<Scalar>, ) -> Result<Self, FrameError>

Conform the index to a datetime frequency with optional fill.

Matches pd.Series.asfreq(freq, method=..., fill_value=...).

Source

pub fn to_period(&self, freq: &str) -> Result<Self, FrameError>

Convert datetime-like index to period-string representation.

Matches pd.Series.to_period(freq) for the supported frequencies.

Source

pub fn to_xarray(&self) -> Result<SeriesXArrayDataArray, FrameError>

Convert Series to xarray DataArray representation.

Matches the practical pd.Series.to_xarray() shape: the index becomes the single coordinate/dimension, and the Series values become the data array.

Source

pub fn describe(&self) -> Result<Self, FrameError>

Generate descriptive statistics for a numeric Series.

Matches pd.Series.describe(). Returns a Series with index [count, mean, std, min, 25%, 50%, 75%, max].

Source

pub fn describe_with_percentiles( &self, percentiles: &[f64], ) -> Result<Self, FrameError>

Generate descriptive statistics with custom percentiles.

Matches pd.Series.describe(percentiles=[...]).

Source

pub fn agg(&self, funcs: &[&str]) -> Result<Self, FrameError>

Aggregate using one or more reduction functions.

Matches pd.Series.agg(["sum", "mean", "std"]). Returns a Series whose index contains the function names and values contain the results.

Source

pub fn xs(&self, key: &IndexLabel) -> Result<Self, FrameError>

Select rows matching the given index key.

Matches s.xs(key). Returns all rows whose index matches key.

Source

pub fn droplevel(&self) -> Result<Self, FrameError>

Return Series with dropped index level(s).

Matches s.droplevel(0) for single-level index.

Source

pub fn unstack(&self) -> Result<DataFrame, FrameError>

Unstack a Series with string-composite index into a DataFrame.

Matches pd.Series.unstack(). Expects index labels in the format “row_key, col_key” (comma-separated composite keys). The first part becomes the row index, the second part becomes column names.

Source

pub fn to_list(&self) -> Vec<Scalar>

Convert Series to a vector of scalars.

Matches series.to_list().

Source

pub fn to_numpy(&self) -> Vec<f64>

Return the underlying values as a flat vector of f64 (numeric coercion).

Matches pd.Series.to_numpy(). Non-numeric values become NaN.

Source

pub fn to_dict(&self) -> Vec<(IndexLabel, Scalar)>

Convert Series to a vector of (label, scalar) pairs.

Matches series.to_dict().

Source

pub fn to_csv(&self, sep: char, include_index: bool) -> String

Serialize the Series to a CSV string.

Matches pd.Series.to_csv().

Source

pub fn to_csv_with_quoting( &self, sep: char, include_index: bool, na_rep: &str, quoting: CsvQuoting, ) -> String

Serialize the Series to a CSV string with quoting control.

Matches pd.Series.to_csv(..., quoting=csv.QUOTE_*).

Source

pub fn to_csv_with_header( &self, sep: char, include_index: bool, na_rep: &str, quoting: CsvQuoting, header: bool, ) -> String

Serialize the Series to a CSV string with quoting and header control.

  • header: if true, write series name as first row; if false, omit header
Source

pub fn to_csv_full( &self, sep: char, include_index: bool, na_rep: &str, quoting: CsvQuoting, header: bool, escapechar: Option<char>, ) -> String

Serialize the Series to a CSV string with full control over all options.

  • escapechar: when using CsvQuoting::None, escape special characters with this
Source

pub fn to_json(&self, orient: &str) -> Result<String, FrameError>

Serialize the Series to a JSON string.

Matches pd.Series.to_json(orient).

  • "split": {"name":"...","index":[...],"data":[...]}
  • "records" / "values": [val1, val2, ...]
  • "index": {"label1": val1, "label2": val2, ...}
Source

pub fn to_string_repr_full( &self, include_index: bool, ) -> Result<String, FrameError>

Render the Series as a tabular string. Matches pd.Series.to_string().

Default (no truncation) form. The include_index parameter mirrors the DataFrame counterpart and lets callers omit the index column.

Source

pub fn to_markdown( &self, include_index: bool, tablefmt: Option<&str>, ) -> Result<String, FrameError>

Render the Series as a Markdown table. Matches pd.Series.to_markdown(tablefmt=None) (Phase A). include_index mirrors the DataFrame counterpart; tablefmt is forwarded to the DataFrame impl which currently supports the pandas defaults.

Source

pub fn to_latex(&self, include_index: bool) -> Result<String, FrameError>

Render the Series as a LaTeX tabular block. Matches pd.Series.to_latex() (Phase A — no escaping/styling options yet).

Source

pub fn to_html(&self, include_index: bool) -> Result<String, FrameError>

Render the Series as an HTML <table> block. Matches pd.Series.to_html() (Phase A). Delegates to the DataFrame counterpart with a single-column frame.

Source

pub fn duplicated(&self) -> Result<Self, FrameError>

Source

pub fn duplicated_keep(&self, keep: DuplicateKeep) -> Result<Self, FrameError>

Mark duplicate values with control over which occurrence to keep.

Matches pd.Series.duplicated(keep=...).

  • First: mark all but the first occurrence as True
  • Last: mark all but the last occurrence as True
  • None: mark all duplicated values as True
Source

pub fn drop_duplicates(&self) -> Result<Self, FrameError>

Remove duplicate values, keeping the first occurrence.

Matches pd.Series.drop_duplicates(keep='first').

Source

pub fn drop_duplicates_keep( &self, keep: DuplicateKeep, ) -> Result<Self, FrameError>

Remove duplicate values with control over which occurrence to keep.

Matches pd.Series.drop_duplicates(keep=...).

  • First: keep the first occurrence of each value
  • Last: keep the last occurrence of each value
  • None: drop all duplicated values entirely
Source

pub fn compare_with(&self, other: &Self) -> Result<DataFrame, FrameError>

Compare this Series with another, showing only differing values.

Matches pd.Series.compare(other). Returns a DataFrame with columns “self” and “other” containing only the rows where the values differ. Equal values are shown as NaN.

Source

pub fn compare(&self, other: &Self) -> Result<DataFrame, FrameError>

Pandas spelling alias for Self::compare_with.

Matches pd.Series.compare(other).

Source

pub fn reindex_like(&self, other: &Self) -> Result<Self, FrameError>

Reindex to match another Series’ index.

Matches pd.Series.reindex_like(other).

Source

pub fn convert_dtypes(&self) -> Result<Self, FrameError>

Convert dtypes to best-possible types.

Matches pd.Series.convert_dtypes(). For Utf8 Series, attempts to parse all values as integers or floats. If all values can be parsed, returns a numeric Series; otherwise returns the original.

Source

pub fn infer_objects(&self) -> Result<Self, FrameError>

Infer object dtypes to best-possible scalar dtypes.

Matches pd.Series.infer_objects() for the current Utf8-backed object representation.

Source

pub fn map_with_na_action( &self, mapping: &[(Scalar, Scalar)], na_action_ignore: bool, ) -> Result<Self, FrameError>

Map values with optional NaN skipping.

Matches pd.Series.map(mapping, na_action='ignore'). When na_action_ignore is true, NaN/Null values are passed through without being looked up in the mapping.

Source

pub fn case_when(&self, cases: &[(Self, Self)]) -> Result<Self, FrameError>

Conditional value assignment.

Matches pd.Series.case_when(caselist). Each case is a pair of (condition_series, value_series). Conditions are evaluated in order; the first matching condition sets the value. Unmatched positions retain the original value.

Source

pub fn rename(&self, name: &str) -> Result<Self, FrameError>

Rename the Series (return a copy with a new name).

Matches pd.Series.rename(name).

Source

pub fn rename_axis(&self, name: &str) -> Result<Self, FrameError>

Rename the index axis (return a copy with a renamed index).

Matches pd.Series.rename_axis(mapper, axis='index'). Distinct from Self::rename which renames the Series itself: rename_axis renames the index AXIS (the label that appears above the index column in Series.info() / Series.to_frame()). Per br-frankenpandas-17c2d (skill /porting-to-rust).

Source

pub fn set_axis(&self, labels: Vec<IndexLabel>) -> Result<Self, FrameError>

Replace the index labels.

Matches pd.Series.set_axis(labels).

Source

pub fn truncate( &self, before: Option<&IndexLabel>, after: Option<&IndexLabel>, ) -> Result<Self, FrameError>

Truncate the Series to rows between before and after labels (inclusive).

Matches pd.Series.truncate(before, after).

Source

pub fn at_time(&self, time: &str) -> Result<Self, FrameError>

Select rows where the time component exactly matches the given time.

Matches s.at_time(time).

Source

pub fn between_time(&self, start: &str, end: &str) -> Result<Self, FrameError>

Select rows where the time component is between start and end.

Matches s.between_time(start_time, end_time).

Source

pub fn first_offset(&self, offset: &str) -> Result<Self, FrameError>

Select initial rows from a DatetimeIndex up to an offset.

Matches pd.Series.first(offset).

Source

pub fn last_offset(&self, offset: &str) -> Result<Self, FrameError>

Select final rows from a DatetimeIndex backward by an offset.

Matches pd.Series.last(offset).

Per br-frankenpandas-a79h9: the missing-last-label case is reported as a CompatibilityRejected error rather than a panic, so callers can recover from inconsistent series state instead of crashing.

Source

pub fn combine<F>(&self, other: &Self, func: F) -> Result<Self, FrameError>
where F: Fn(&Scalar, &Scalar) -> Scalar,

Combine two Series element-wise using a function.

Matches pd.Series.combine(other, func). Aligns on the union of index labels before applying the function element-wise. The function receives two scalars (one from self, one from other) and returns a scalar.

Source

pub fn explode(&self, sep: &str) -> Result<Self, FrameError>

Explode a Series of string values by splitting on a separator.

Matches pd.Series.explode() for list-like string values. Each string is split by sep and each piece becomes its own row. The index label is repeated for each piece.

Source

pub fn rolling(&self, window: usize, min_periods: Option<usize>) -> Rolling<'_>

Create a rolling window view of this Series.

Matches series.rolling(window, min_periods=None).

Examples found in repository?
examples/bench_rolling_var.rs (line 68)
64fn run_api(s: &Series, window: usize, min_periods: Option<usize>, center: bool, a: Agg) -> Series {
65    let r = if center {
66        s.rolling_center(window, min_periods)
67    } else {
68        s.rolling(window, min_periods)
69    };
70    match a {
71        Agg::Var => r.var(),
72        Agg::Std => r.std(),
73        Agg::Skew => r.skew(),
74        Agg::Kurt => r.kurt(),
75        Agg::Sem => r.sem(),
76        Agg::Prod => r.prod(),
77    }
78    .unwrap()
79}
Source

pub fn rolling_with_center( &self, window: usize, min_periods: Option<usize>, center: bool, ) -> Rolling<'_>

Create a rolling window with explicit center parameter.

Matches pd.Series.rolling(window, min_periods, center).

Source

pub fn rolling_center( &self, window: usize, min_periods: Option<usize>, ) -> Rolling<'_>

Create a centered rolling window over this Series.

Matches pd.Series.rolling(window, center=True).

Examples found in repository?
examples/bench_rolling_var.rs (line 66)
64fn run_api(s: &Series, window: usize, min_periods: Option<usize>, center: bool, a: Agg) -> Series {
65    let r = if center {
66        s.rolling_center(window, min_periods)
67    } else {
68        s.rolling(window, min_periods)
69    };
70    match a {
71        Agg::Var => r.var(),
72        Agg::Std => r.std(),
73        Agg::Skew => r.skew(),
74        Agg::Kurt => r.kurt(),
75        Agg::Sem => r.sem(),
76        Agg::Prod => r.prod(),
77    }
78    .unwrap()
79}
Source

pub fn expanding(&self, min_periods: Option<usize>) -> Expanding<'_>

Create an expanding window view of this Series.

Matches series.expanding(min_periods=1).

Source

pub fn ewm(&self, span: Option<f64>, alpha: Option<f64>) -> Ewm<'_>

Create an exponentially weighted moving window view of this Series.

Matches series.ewm(span=...). Either span or alpha must be provided.

  • span: Specify decay in terms of span. alpha = 2 / (span + 1).
  • alpha: Specify smoothing factor directly, 0 < alpha <= 1.
Source

pub fn resample(&self, freq: &str) -> Resample<'_>

Create a resampler view for time-based downsampling.

Matches series.resample(freq) where freq is one of:

  • “Y” or “A”: yearly (bucket by YYYY)
  • “M”: monthly (bucket by YYYY-MM)
  • “D”: daily (bucket by YYYY-MM-DD)

The Series index must contain Utf8 datetime-like labels (ISO format).

Source

pub fn autocorr(&self, lag: usize) -> Result<f64, FrameError>

Compute autocorrelation at the specified lag.

Matches series.autocorr(lag=1). Computes the Pearson correlation between the Series and its lagged copy.

Source

pub fn dot(&self, other: &Self) -> Result<f64, FrameError>

Compute the dot product with another Series.

Matches series.dot(other) / series @ other.

Source

pub fn rank( &self, method: &str, ascending: bool, na_option: &str, ) -> Result<Self, FrameError>

Rank values in the Series.

method: “average” (default), “min”, “max”, “first”, “dense” ascending: rank direction (default true = smallest gets rank 1) na_option: “keep” (NaN stays NaN), “top” (NaN gets lowest ranks), “bottom” (NaN gets highest ranks)

Source

pub fn rank_with_pct( &self, method: &str, ascending: bool, na_option: &str, pct: bool, ) -> Result<Self, FrameError>

Source

pub fn corr(&self, other: &Self) -> Result<f64, FrameError>

Compute the Pearson correlation with another Series.

Source

pub fn cov_with(&self, other: &Self) -> Result<f64, FrameError>

Compute the sample covariance with another Series.

Source

pub fn cov(&self, other: &Self) -> Result<f64, FrameError>

Pandas spelling alias for Self::cov_with.

Matches pd.Series.cov(other).

Source

pub fn cov_with_options( &self, other: &Self, min_periods: Option<usize>, ddof: usize, ) -> Result<f64, FrameError>

Compute covariance with explicit min_periods + ddof, matching pd.Series.cov(other, min_periods=, ddof=).

Per br-frankenpandas-9ac700:

  • min_periods: minimum count of valid (both non-null) pairs; below this, returns NaN.
  • ddof: delta degrees of freedom; divisor is count - ddof. Defaults map: ddof=0 population, ddof=1 sample (pandas default).
Source

pub fn corr_spearman(&self, other: &Self) -> Result<f64, FrameError>

Compute the Spearman rank correlation with another Series.

Ranks both Series and then computes Pearson correlation on the ranks.

Source

pub fn corr_kendall(&self, other: &Self) -> Result<f64, FrameError>

Compute the Kendall tau-b correlation with another Series.

Examples found in repository?
examples/bench_kendall.rs (line 44)
21fn golden() -> String {
22    let mut out = String::new();
23    let cases: &[(&[f64], &[f64])] = &[
24        // ties in both x and y
25        (
26            &[1.0, 2.0, 2.0, 3.0, 3.0, 3.0],
27            &[1.0, 1.0, 2.0, 2.0, 3.0, 3.0],
28        ),
29        // joint ties (identical (x,y) pairs)
30        (&[1.0, 1.0, 2.0, 2.0], &[5.0, 5.0, 9.0, 9.0]),
31        // discordant-heavy with ties
32        (&[1.0, 2.0, 3.0, 4.0, 4.0], &[5.0, 4.0, 3.0, 2.0, 2.0]),
33        // all x tied -> denom NaN
34        (&[7.0, 7.0, 7.0], &[1.0, 2.0, 3.0]),
35        // mixed integers as floats, larger
36        (
37            &[1.0, 2.0, 2.0, 3.0, 1.0, 2.0, 3.0, 3.0, 1.0, 2.0],
38            &[2.0, 2.0, 1.0, 3.0, 1.0, 2.0, 3.0, 1.0, 2.0, 3.0],
39        ),
40    ];
41    for (i, (x, y)) in cases.iter().enumerate() {
42        let a = s_from(x);
43        let b = s_from(y);
44        let tau = a.corr_kendall(&b).unwrap();
45        out.push_str(&format!("case{i}: {:.17e}\n", tau));
46    }
47    out
48}
49
50/// Verbatim copy of the original O(n²) pairwise tau-b loop, as an independent
51/// reference for the randomized cross-check.
52fn kendall_ref(x: &[f64], y: &[f64]) -> f64 {
53    let n = x.len();
54    if n < 2 {
55        return f64::NAN;
56    }
57    let (mut con, mut dis, mut tx, mut ty) = (0_i64, 0_i64, 0_i64, 0_i64);
58    for i in 0..n {
59        for j in (i + 1)..n {
60            let dx = x[i] - x[j];
61            let dy = y[i] - y[j];
62            if dx.abs() < f64::EPSILON && dy.abs() < f64::EPSILON {
63                tx += 1;
64                ty += 1;
65            } else if dx.abs() < f64::EPSILON {
66                tx += 1;
67            } else if dy.abs() < f64::EPSILON {
68                ty += 1;
69            } else if (dx > 0.0 && dy > 0.0) || (dx < 0.0 && dy < 0.0) {
70                con += 1;
71            } else {
72                dis += 1;
73            }
74        }
75    }
76    let n_pairs = (n * (n - 1)) as f64 / 2.0;
77    let denom = ((n_pairs - tx as f64) * (n_pairs - ty as f64)).sqrt();
78    if denom < f64::EPSILON {
79        f64::NAN
80    } else {
81        (con - dis) as f64 / denom
82    }
83}
84
85fn cross_check() -> (usize, usize) {
86    // LCG for deterministic pseudo-random integer-tied datasets.
87    let mut state: u64 = 0x2545F4914F6CDD1D;
88    let mut next = || {
89        state = state
90            .wrapping_mul(6364136223846793005)
91            .wrapping_add(1442695040888963407);
92        state
93    };
94    let (mut ok, mut bad) = (0usize, 0usize);
95    for _ in 0..4000 {
96        let n = (next() % 30) as usize + 2;
97        let range = next() % 6 + 1; // small range -> many ties
98        let xs: Vec<f64> = (0..n).map(|_| (next() % range) as f64).collect();
99        let ys: Vec<f64> = (0..n).map(|_| (next() % range) as f64).collect();
100        let got = s_from(&xs).corr_kendall(&s_from(&ys)).unwrap();
101        let want = kendall_ref(&xs, &ys);
102        // bit-for-bit (NaN compares equal by bits here since both produce the
103        // canonical NaN from the same sqrt path).
104        if got.to_bits() == want.to_bits() || (got.is_nan() && want.is_nan()) {
105            ok += 1;
106        } else {
107            bad += 1;
108            if bad <= 3 {
109                eprintln!("MISMATCH n={n} got={got:?} want={want:?}");
110            }
111        }
112    }
113    (ok, bad)
114}
115
116fn main() {
117    let g = golden();
118    print!("GOLDEN_BEGIN\n{g}GOLDEN_END\n");
119
120    let (ok, bad) = cross_check();
121    println!("CROSSCHECK ok={ok} bad={bad}");
122
123    // Large tied dataset: values in a small range force many ties, so the old
124    // path takes the O(n²) loop (no-tie fast path bails on ties).
125    let n: usize = 40_000;
126    let xs: Vec<f64> = (0..n).map(|i| ((i * 7) % 50) as f64).collect();
127    let ys: Vec<f64> = (0..n).map(|i| ((i * 13) % 40) as f64).collect();
128    let a = s_from(&xs);
129    let b = s_from(&ys);
130
131    let t = Instant::now();
132    let tau = a.corr_kendall(&b).unwrap();
133    let d = t.elapsed();
134
135    println!(
136        "TIMING n={n} corr_kendall={:.3}ms tau={:.6}",
137        d.as_secs_f64() * 1e3,
138        tau
139    );
140}
Source

pub fn groupby<'a>( &'a self, by: &'a Series, ) -> Result<SeriesGroupBy<'a>, FrameError>

Group the Series by another Series of the same length.

Matches pd.Series.groupby(by). Returns a SeriesGroupBy which supports aggregation methods (sum, mean, count, min, max, etc.).

Examples found in repository?
examples/bench_groupby_shift.rs (line 41)
19fn main() {
20    let args: Vec<String> = std::env::args().collect();
21    let n: usize = args.get(1).and_then(|s| s.parse().ok()).unwrap_or(1_000_000);
22    let iters: usize = args.get(2).and_then(|s| s.parse().ok()).unwrap_or(30);
23    let groups = 100usize;
24
25    let labels: Vec<IndexLabel> = (0..n as i64).map(IndexLabel::Int64).collect();
26    let keys: Vec<i64> = (0..n).map(|i| (i % groups) as i64).collect();
27    let vals: Vec<f64> = (0..n).map(|i| (i.wrapping_mul(37) % 9973) as f64 * 0.25).collect();
28    let value = Series::new(
29        "v".to_string(),
30        Index::new(labels.clone()),
31        Column::from_f64_values(vals),
32    )
33    .unwrap();
34    let key = Series::new(
35        "k".to_string(),
36        Index::new(labels),
37        Column::from_i64_values(keys),
38    )
39    .unwrap();
40
41    let out = value.groupby(&key).unwrap().shift(1).unwrap();
42    let mut chk: u64 = 0xcbf29ce484222325;
43    for v in out.values() {
44        let bits = match v {
45            Scalar::Float64(f) => f.to_bits(),
46            _ => 0xDEAD_BEEF_DEAD_BEEF,
47        };
48        chk = (chk ^ bits).wrapping_mul(0x100000001b3);
49    }
50
51    let mut sink = 0usize;
52    let start = Instant::now();
53    for _ in 0..iters {
54        let s = black_box(value.groupby(&key).unwrap().shift(1).unwrap());
55        sink ^= s.len();
56    }
57    let elapsed = start.elapsed();
58    println!(
59        "groupby_shift n={n} iters={iters}: {:.3} ms/iter (chk={chk:016x} sink={sink})",
60        elapsed.as_secs_f64() * 1000.0 / iters as f64
61    );
62}
More examples
Hide additional examples
examples/bench_take_gather.rs (line 74)
27fn golden() -> String {
28    let mut out = String::new();
29
30    // Series::take across dtypes, negative + duplicate indices.
31    let s = s_i64(vec![10, 20, 30, 40, 50]);
32    let r = s.take(&[4, 0, -1, 2, -5, 2]).unwrap();
33    out.push_str(&format!("take_lbls={:?}\n", r.index().labels()));
34    out.push_str(&format!("take_vals={:?}\n", r.values()));
35    out.push_str(&format!("take_oob_err={}\n", s.take(&[99]).is_err()));
36
37    let f = s_scalars(vec![
38        Scalar::Float64(1.5),
39        Scalar::Float64(f64::NAN),
40        Scalar::Float64(-3.0),
41    ]);
42    out.push_str(&format!(
43        "take_f64={:?}\n",
44        f.take(&[2, 1, 0]).unwrap().values()
45    ));
46    let ni = s_scalars(vec![
47        Scalar::Int64(7),
48        Scalar::Null(NullKind::NaN),
49        Scalar::Int64(9),
50    ]);
51    out.push_str(&format!(
52        "take_ni={:?}\n",
53        ni.take(&[1, 2, 0]).unwrap().values()
54    ));
55    let u = s_scalars(
56        vec!["a", "b", "c"]
57            .into_iter()
58            .map(|x| Scalar::Utf8(x.into()))
59            .collect(),
60    );
61    out.push_str(&format!(
62        "take_utf8={:?}\n",
63        u.take(&[2, -3]).unwrap().values()
64    ));
65
66    // SeriesGroupBy gather paths (nlargest / head) route through take_positions.
67    let data = s_i64(vec![5, 1, 9, 3, 7, 2, 8]);
68    let keys = s_scalars(
69        vec!["a", "b", "a", "b", "a", "b", "a"]
70            .into_iter()
71            .map(|x| Scalar::Utf8(x.into()))
72            .collect(),
73    );
74    let gb = data.groupby(&keys).unwrap();
75    let nl = gb.nlargest(2).unwrap();
76    out.push_str(&format!("gb_nlargest_lbls={:?}\n", nl.index().labels()));
77    out.push_str(&format!("gb_nlargest_vals={:?}\n", nl.values()));
78    let hd = data.groupby(&keys).unwrap().head(1).unwrap();
79    out.push_str(&format!("gb_head_vals={:?}\n", hd.values()));
80    out
81}
Source

pub fn str(&self) -> StringAccessor<'_>

Access string methods on a Utf8 Series (analogous to pandas.Series.str).

Examples found in repository?
examples/bench_translate.rs (line 30)
25fn golden() -> String {
26    let mut out = String::new();
27    let s = s_from(vec!["hello world", "abcXYZ", "", "duplicate-d"]);
28
29    // basic 1:1 replacement
30    let r = s.str().translate("lo", "LO").unwrap();
31    out.push_str(&format!("basic={:?}\n", r.values()));
32
33    // `to` shorter than `from` => extra source chars are DELETED. 'o'->'0',
34    // but 'l' (index 1) has no target so every 'l' is removed.
35    let r2 = s.str().translate("ol", "0").unwrap();
36    out.push_str(&format!("delete={:?}\n", r2.values()));
37
38    // duplicate source char in `from`: first occurrence wins ('d'->'1', not '2')
39    let r3 = s.str().translate("dd", "12").unwrap();
40    out.push_str(&format!("dupsrc={:?}\n", r3.values()));
41
42    // empty table: identity
43    let r4 = s.str().translate("", "").unwrap();
44    out.push_str(&format!("empty={:?}\n", r4.values()));
45    out
46}
47
48fn main() {
49    let g = golden();
50    print!("GOLDEN_BEGIN\n{g}GOLDEN_END\n");
51
52    // Large translation table + many long strings.
53    let from: String = (0u32..2000).filter_map(char::from_u32).collect();
54    let to: String = (1000u32..3000).filter_map(char::from_u32).collect();
55    // Strings made of chars near the END of the `from` table: the linear scan
56    // must traverse ~all of `from` per char (the realistic O(|from|) cost).
57    let base: String = (1800u32..2000).filter_map(char::from_u32).collect();
58    let one = base.repeat(20); // ~4000 chars/string
59    let n = 2_000;
60    let s = s_from(vec![one.as_str(); n]);
61
62    // warmup
63    let _ = s.str().translate(&from, &to).unwrap();
64
65    let t = Instant::now();
66    let r = s.str().translate(&from, &to).unwrap();
67    let d = t.elapsed();
68    assert_eq!(r.len(), n);
69
70    println!(
71        "TIMING n={n} from_len={} translate={:.3}ms",
72        from.chars().count(),
73        d.as_secs_f64() * 1e3
74    );
75}
More examples
Hide additional examples
examples/bench_contains_any.rs (line 29)
25fn golden() -> String {
26    let mut out = String::new();
27    let s = s_from(vec!["hello world", "foobar", "BAZ qux", "", "a.b+c"]);
28
29    let r = s.str().contains_any(&["world", "qux"]).unwrap();
30    out.push_str(&format!("hit={:?}\n", r.values()));
31
32    // Regex metacharacters must be treated as LITERALS.
33    let r2 = s.str().contains_any(&["a.b+c", "zz"]).unwrap();
34    out.push_str(&format!("literal_meta={:?}\n", r2.values()));
35
36    // Case sensitive (no match for lowercase 'baz').
37    let r3 = s.str().contains_any(&["baz"]).unwrap();
38    out.push_str(&format!("case={:?}\n", r3.values()));
39
40    // Empty pattern set => all false.
41    let r4 = s.str().contains_any(&[]).unwrap();
42    out.push_str(&format!("empty={:?}\n", r4.values()));
43
44    // Empty-string pattern matches every (non-null) string.
45    let r5 = s.str().contains_any(&["", "zz"]).unwrap();
46    out.push_str(&format!("empty_pat={:?}\n", r5.values()));
47    out
48}
49
50fn main() {
51    let g = golden();
52    print!("GOLDEN_BEGIN\n{g}GOLDEN_END\n");
53
54    // Many patterns, mostly-missing, over many medium strings (worst case:
55    // every pattern scanned per string in the naive path).
56    let pats_owned: Vec<String> = (0..200).map(|i| format!("needle{i:04}xyz")).collect();
57    let pats: Vec<&str> = pats_owned.iter().map(String::as_str).collect();
58    let base = "the quick brown fox jumps over the lazy dog ".repeat(4);
59    let n = 20_000;
60    let s = s_from(vec![base.as_str(); n]);
61
62    // warmup
63    let _ = s.str().contains_any(&pats).unwrap();
64
65    let t = Instant::now();
66    let r = s.str().contains_any(&pats).unwrap();
67    let d = t.elapsed();
68    assert_eq!(r.len(), n);
69
70    println!(
71        "TIMING n={n} npats={} contains_any={:.3}ms",
72        pats.len(),
73        d.as_secs_f64() * 1e3
74    );
75}
examples/bench_startswith_any.rs (line 29)
25fn golden() -> String {
26    let mut out = String::new();
27    let s = s_from(vec!["https://a.com", "ftp://x", "file.txt", "", "a.b+c"]);
28
29    let r = s.str().startswith_any(&["https://", "ftp://"]).unwrap();
30    out.push_str(&format!("sw_hit={:?}\n", r.values()));
31    // metacharacters stay literal
32    let r2 = s.str().startswith_any(&["a.b+c"]).unwrap();
33    out.push_str(&format!("sw_meta={:?}\n", r2.values()));
34    let r3 = s.str().endswith_any(&[".txt", ".com"]).unwrap();
35    out.push_str(&format!("ew_hit={:?}\n", r3.values()));
36    // empty pattern set => all false
37    let r4 = s.str().startswith_any(&[]).unwrap();
38    out.push_str(&format!("empty={:?}\n", r4.values()));
39    // empty-string pattern matches every non-null string
40    let r5 = s.str().endswith_any(&["", "zz"]).unwrap();
41    out.push_str(&format!("empty_pat={:?}\n", r5.values()));
42
43    // with_na variants (null fill).
44    let sn = Series::from_values(
45        "s",
46        vec![IndexLabel::Int64(0), IndexLabel::Int64(1)],
47        vec![
48            Scalar::Utf8("https://z".into()),
49            Scalar::Null(fp_types::NullKind::NaN),
50        ],
51    )
52    .unwrap();
53    let rn = sn
54        .str()
55        .startswith_any_with_na(&["https://"], Some(true))
56        .unwrap();
57    out.push_str(&format!("na_fill={:?}\n", rn.values()));
58    out
59}
60
61fn main() {
62    let g = golden();
63    print!("GOLDEN_BEGIN\n{g}GOLDEN_END\n");
64
65    // Worst case: many prefixes sharing a long common stem.
66    let pats_owned: Vec<String> = (0..200)
67        .map(|i| format!("https://cdn.example.com/path/{i:04}/"))
68        .collect();
69    let pats: Vec<&str> = pats_owned.iter().map(String::as_str).collect();
70    let one = "https://cdn.example.com/path/9999/asset/file/deep/name.bin";
71    let n = 40_000;
72    let s = s_from(vec![one; n]);
73
74    let _ = s.str().startswith_any(&pats).unwrap(); // warmup
75
76    let t = Instant::now();
77    let r = s.str().startswith_any(&pats).unwrap();
78    let d = t.elapsed();
79    assert_eq!(r.len(), n);
80
81    println!(
82        "TIMING n={n} npats={} startswith_any={:.3}ms",
83        pats.len(),
84        d.as_secs_f64() * 1e3
85    );
86}
Source

pub fn dt(&self) -> DatetimeAccessor<'_>

Access datetime components of this Series.

Matches pd.Series.dt. Extracts components from ISO 8601 formatted string values.

Source

pub fn cat(&self) -> Option<CategoricalAccessor<'_>>

Access categorical methods on this Series.

Matches pd.Series.cat. Returns None if the Series is not categorical.

Source

pub fn sparse(&self) -> Option<SparseAccessor<'_>>

Access sparse methods on this Series.

Matches the pd.Series.sparse namespace for dense-backed sparse descriptors. Returns None if the Series is not sparse.

Source

pub fn list(&self) -> ListAccessor<'_>

Access list-array methods on this Series.

Matches the pandas Series.list namespace shape. Until fp-types grows a first-class list scalar, FrankenPandas supports a concrete JSON-array-backed slice for UTF-8 object values plus missing values.

Source

pub fn struct(&self) -> StructAccessor<'_>

Access struct-array methods on this Series.

Matches the pandas Series.struct namespace shape. Until fp-types grows a first-class struct scalar, FrankenPandas supports a concrete JSON-object-backed slice for UTF-8 object values plus missing values. Rust callers use raw identifier syntax: series.r#struct().

Source

pub fn is_categorical(&self) -> bool

Returns true if this Series has categorical metadata.

Source

pub fn is_sparse(&self) -> bool

Returns true if this Series has sparse dtype metadata.

Source

pub fn from_categorical( name: impl Into<String>, values: Vec<Scalar>, ordered: bool, ) -> Result<Self, FrameError>

Create a categorical Series from values.

Matches pd.Categorical(values). Infers categories from unique values. Stores integer codes as the column data.

Source

pub fn from_categorical_codes( name: impl Into<String>, codes: Vec<i64>, categories: Vec<Scalar>, ordered: bool, ) -> Result<Self, FrameError>

Create a categorical Series from explicit codes and categories.

Matches pd.Categorical.from_codes(codes, categories).

Source

pub fn from_sparse_dense( name: impl Into<String>, index_labels: Vec<IndexLabel>, values: Vec<Scalar>, value_dtype: DType, fill_value: Scalar, ) -> Result<Self, FrameError>

Create a sparse Series from dense values.

Matches the pandas SparseDtype(value_dtype, fill_value) contract for the Series-level dtype/accessor surface. The current storage remains dense; compressed sparse storage is tracked separately in fp-columnar.

Source

pub fn apply_fn<F>(&self, func: F) -> Result<Self, FrameError>
where F: Fn(&Scalar) -> Scalar,

Apply a closure element-wise to produce a new Series.

Source

pub fn apply_fn_na<F>(&self, func: F) -> Result<Self, FrameError>
where F: Fn(&Scalar) -> Scalar,

Apply a function with na_action='ignore'.

Matches series.apply(func, na_action='ignore'). Skips NaN/null values, preserving them in the output unchanged.

Source

pub fn map_fn<F>(&self, func: F) -> Result<Self, FrameError>
where F: Fn(&Scalar) -> Result<Scalar, FrameError>,

Map values using a failable closure.

Like apply_fn but the closure returns Result<Scalar, FrameError>, enabling transformations that may fail (type conversion, parsing, etc.). Matches the general pattern of pandas Series.map(func).

Source

pub fn map_dict( &self, mapping: &BTreeMap<Scalar, Scalar>, ) -> Result<Self, FrameError>

Source

pub fn map_values( &self, mapping: &HashMap<String, Scalar>, ) -> Result<Self, FrameError>

Map values using a dictionary (HashMap).

Values not found in the map become NaN (like pandas Series.map(dict)).

Trait Implementations§

Source§

impl Clone for Series

Source§

fn clone(&self) -> Series

Returns a duplicate of the value. Read more
1.0.0 (const: unstable) · Source§

fn clone_from(&mut self, source: &Self)

Performs copy-assignment from source. Read more
Source§

impl Debug for Series

Source§

fn fmt(&self, f: &mut Formatter<'_>) -> Result

Formats the value using the given formatter. Read more
Source§

impl<'de> Deserialize<'de> for Series

Source§

fn deserialize<__D>(__deserializer: __D) -> Result<Self, __D::Error>
where __D: Deserializer<'de>,

Deserialize this value from the given Serde deserializer. Read more
Source§

impl Display for Series

Source§

fn fmt(&self, f: &mut Formatter<'_>) -> Result

Formats the value using the given formatter. Read more
Source§

impl PartialEq for Series

Source§

fn eq(&self, other: &Series) -> bool

Tests for self and other values to be equal, and is used by ==.
1.0.0 (const: unstable) · Source§

fn ne(&self, other: &Rhs) -> bool

Tests for !=. The default implementation is almost always sufficient, and should not be overridden without very good reason.
Source§

impl Serialize for Series

Source§

fn serialize<__S>(&self, __serializer: __S) -> Result<__S::Ok, __S::Error>
where __S: Serializer,

Serialize this value into the given Serde serializer. Read more
Source§

impl StructuralPartialEq for Series

Auto Trait Implementations§

Blanket Implementations§

Source§

impl<T> Any for T
where T: 'static + ?Sized,

Source§

fn type_id(&self) -> TypeId

Gets the TypeId of self. Read more
Source§

impl<T> Borrow<T> for T
where T: ?Sized,

Source§

fn borrow(&self) -> &T

Immutably borrows from an owned value. Read more
Source§

impl<T> BorrowMut<T> for T
where T: ?Sized,

Source§

fn borrow_mut(&mut self) -> &mut T

Mutably borrows from an owned value. Read more
Source§

impl<T> CloneToUninit for T
where T: Clone,

Source§

unsafe fn clone_to_uninit(&self, dest: *mut u8)

🔬This is a nightly-only experimental API. (clone_to_uninit)
Performs copy-assignment from self to dest. Read more
Source§

impl<T> DeserializeOwned for T
where T: for<'de> Deserialize<'de>,

Source§

impl<T> From<T> for T

Source§

fn from(t: T) -> T

Returns the argument unchanged.

Source§

impl<T, U> Into<U> for T
where U: From<T>,

Source§

fn into(self) -> U

Calls U::from(self).

That is, this conversion is whatever the implementation of From<T> for U chooses to do.

Source§

impl<T> Same for T

Source§

type Output = T

Should always be Self
Source§

impl<T> ToOwned for T
where T: Clone,

Source§

type Owned = T

The resulting type after obtaining ownership.
Source§

fn to_owned(&self) -> T

Creates owned data from borrowed data, usually by cloning. Read more
Source§

fn clone_into(&self, target: &mut T)

Uses borrowed data to replace owned data, usually by cloning. Read more
Source§

impl<T> ToString for T
where T: Display + ?Sized,

Source§

fn to_string(&self) -> String

Converts the given value to a String. Read more
Source§

impl<T, U> TryFrom<U> for T
where U: Into<T>,

Source§

type Error = Infallible

The type returned in the event of a conversion error.
Source§

fn try_from(value: U) -> Result<T, <T as TryFrom<U>>::Error>

Performs the conversion.
Source§

impl<T, U> TryInto<U> for T
where U: TryFrom<T>,

Source§

type Error = <U as TryFrom<T>>::Error

The type returned in the event of a conversion error.
Source§

fn try_into(self) -> Result<U, <U as TryFrom<T>>::Error>

Performs the conversion.