Skip to content

Feature: Polars integration #60

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Open
wants to merge 9 commits into
base: main
Choose a base branch
from
Open
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 3 additions & 0 deletions downsample_rs/Cargo.toml
Original file line number Diff line number Diff line change
@@ -9,6 +9,9 @@ license = "MIT"
[dependencies]
# TODO: perhaps use polars?
argminmax = { version = "0.6.1", features = ["half"] }
# For some reason we need to explicitely add chrono, otherwise polars refuses to compile?
chrono = "0.4.31"
polars = { version = "0.33.2", features = ["lazy", "streaming", "zip_with"] }
half = { version = "2.3.1", default-features = false , features=["num-traits"], optional = true}
num-traits = { version = "0.2.17", default-features = false }
once_cell = "1"
115 changes: 115 additions & 0 deletions downsample_rs/src/helpers.rs
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
use num_traits::AsPrimitive;
use polars::prelude::{ChunkAgg, ChunkAnyValue, ChunkedArray, Float64Type};

use crate::types::Num;

@@ -31,3 +32,117 @@ where
self.iter().fold(0f64, |acc, &x| acc + x.as_()) as f64 / self.len() as f64
}
}

impl<T> Average for Vec<T>
where
T: Num + AsPrimitive<f64>,
{
fn average(&self) -> f64 {
self.iter().fold(0f64, |acc, &x| acc + x.as_()) as f64 / self.len() as f64
}
}

pub trait LttbParam {
type IterType: Iterator<Item = f64>;
type SliceType: LttbParam;

fn slice(&self, start_idx: usize, end_idx: usize) -> Self::SliceType;

fn get(&self, index: usize) -> f64;

fn into_iter(&self) -> Self::IterType;

fn len(&self) -> usize;

fn average(&self) -> f64;
}

impl<T> LttbParam for [T]
where
T: Num + AsPrimitive<f64>,
{
type IterType = std::vec::IntoIter<f64>;
type SliceType = std::vec::Vec<f64>;

fn slice(&self, start_idx: usize, end_idx: usize) -> Self::SliceType {
self[start_idx..end_idx].iter().map(|v| v.as_()).collect()
}

fn get(&self, index: usize) -> f64 {
self[index].as_()
}

fn into_iter(&self) -> Self::IterType {
IntoIterator::into_iter(self.iter().map(|v| v.as_()).collect::<Vec<f64>>())
}

fn len(&self) -> usize {
self.len()
}

fn average(&self) -> f64 {
Average::average(self)
}
}

impl<T> LttbParam for Vec<T>
where
T: Num + AsPrimitive<f64>,
{
type IterType = std::vec::IntoIter<f64>;
type SliceType = std::vec::Vec<f64>;

fn slice(&self, start_idx: usize, end_idx: usize) -> Self::SliceType {
self[start_idx..end_idx].iter().map(|v| v.as_()).collect()
}

fn get(&self, index: usize) -> f64 {
self[index].as_()
}

fn into_iter(&self) -> Self::IterType {
IntoIterator::into_iter(self.iter().map(|v| v.as_()).collect::<Vec<f64>>())
}

fn len(&self) -> usize {
self.len()
}

fn average(&self) -> f64 {
Average::average(self)
}
}

impl LttbParam for ChunkedArray<Float64Type> {
type IterType = std::vec::IntoIter<f64>;
type SliceType = ChunkedArray<Float64Type>;

fn slice(&self, start_idx: usize, end_idx: usize) -> Self::SliceType {
self.slice(start_idx as i64, end_idx - start_idx)
}

fn get(&self, index: usize) -> f64 {
match self
.get_any_value(index)
.unwrap()
.cast(&polars::prelude::DataType::Float64)
.unwrap()
{
polars::prelude::AnyValue::Float64(x) => x,
_ => unreachable!(), // this can never be reached, as it should have panicked when casting
}
}

fn into_iter(&self) -> Self::IterType {
// TODO: fix this so we don't do any needless copying
self.into_no_null_iter().collect::<Vec<f64>>().into_iter()
}

fn len(&self) -> usize {
self.len()
}

fn average(&self) -> f64 {
self.mean().unwrap_or(0.0)
}
}
Loading