Skip to content

Commit

Permalink
impl NamedFrom for ChunkedArray
Browse files Browse the repository at this point in the history
  • Loading branch information
ritchie46 committed Dec 5, 2021
1 parent 7bf795a commit a512a3e
Show file tree
Hide file tree
Showing 5 changed files with 127 additions and 119 deletions.
4 changes: 2 additions & 2 deletions polars/polars-core/src/chunked_array/ops/aggregate.rs
Original file line number Diff line number Diff line change
Expand Up @@ -588,7 +588,7 @@ mod test {

#[test]
fn test_mean() {
let ca = Float32Chunked::new_from_opt_slice("", &[Some(1.0), Some(2.0), None]);
let ca = Float32Chunked::new("", &[Some(1.0), Some(2.0), None]);
assert_eq!(ca.mean().unwrap(), 1.5);
// all mean_as_series are cast to f64.
assert_eq!(ca.mean_as_series().f64().unwrap().get(0).unwrap(), 1.5);
Expand All @@ -600,7 +600,7 @@ mod test {

#[test]
fn test_quantile_all_null() {
let ca = Float32Chunked::new_from_opt_slice("", &[None, None, None]);
let ca = Float32Chunked::new("", &[None, None, None]);
let out = ca.quantile(0.9).unwrap();
assert_eq!(out, None)
}
Expand Down
1 change: 1 addition & 0 deletions polars/polars-core/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@ pub mod export;
mod fmt;
pub mod frame;
pub mod functions;
mod named_from;
pub mod prelude;
#[cfg(feature = "serde")]
#[cfg_attr(docsrs, doc(cfg(feature = "serde")))]
Expand Down
121 changes: 121 additions & 0 deletions polars/polars-core/src/named_from.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,121 @@
use crate::chunked_array::builder::get_list_builder;
use crate::prelude::*;
use std::borrow::Cow;

pub trait NamedFrom<T, Phantom: ?Sized> {
/// Initialize by name and values.
fn new(name: &str, _: T) -> Self;
}
//
macro_rules! impl_named_from {
($type:ty, $polars_type:ident, $method:ident) => {
impl<T: AsRef<$type>> NamedFrom<T, $type> for Series {
fn new(name: &str, v: T) -> Self {
ChunkedArray::<$polars_type>::$method(name, v.as_ref()).into_series()
}
}
impl<T: AsRef<$type>> NamedFrom<T, $type> for ChunkedArray<$polars_type> {
fn new(name: &str, v: T) -> Self {
ChunkedArray::<$polars_type>::$method(name, v.as_ref())
}
}
};
}

impl<'a, T: AsRef<[&'a str]>> NamedFrom<T, [&'a str]> for Series {
fn new(name: &str, v: T) -> Self {
Utf8Chunked::new_from_slice(name, v.as_ref()).into_series()
}
}
impl<'a, T: AsRef<[Option<&'a str>]>> NamedFrom<T, [Option<&'a str>]> for Series {
fn new(name: &str, v: T) -> Self {
Utf8Chunked::new_from_opt_slice(name, v.as_ref()).into_series()
}
}

impl<'a, T: AsRef<[Cow<'a, str>]>> NamedFrom<T, [Cow<'a, str>]> for Series {
fn new(name: &str, v: T) -> Self {
Utf8Chunked::new_from_iter(name, v.as_ref().iter().map(|value| value.as_ref()))
.into_series()
}
}
impl<'a, T: AsRef<[Option<Cow<'a, str>>]>> NamedFrom<T, [Option<Cow<'a, str>>]> for Series {
fn new(name: &str, v: T) -> Self {
Utf8Chunked::new_from_opt_iter(
name,
v.as_ref()
.iter()
.map(|opt| opt.as_ref().map(|value| value.as_ref())),
)
.into_series()
}
}

impl_named_from!([String], Utf8Type, new_from_slice);
impl_named_from!([bool], BooleanType, new_from_slice);
#[cfg(feature = "dtype-u8")]
impl_named_from!([u8], UInt8Type, new_from_slice);
#[cfg(feature = "dtype-u16")]
impl_named_from!([u16], UInt16Type, new_from_slice);
impl_named_from!([u32], UInt32Type, new_from_slice);
impl_named_from!([u64], UInt64Type, new_from_slice);
#[cfg(feature = "dtype-i8")]
impl_named_from!([i8], Int8Type, new_from_slice);
#[cfg(feature = "dtype-i16")]
impl_named_from!([i16], Int16Type, new_from_slice);
impl_named_from!([i32], Int32Type, new_from_slice);
impl_named_from!([i64], Int64Type, new_from_slice);
impl_named_from!([f32], Float32Type, new_from_slice);
impl_named_from!([f64], Float64Type, new_from_slice);
impl_named_from!([Option<String>], Utf8Type, new_from_opt_slice);
impl_named_from!([Option<bool>], BooleanType, new_from_opt_slice);
#[cfg(feature = "dtype-u8")]
impl_named_from!([Option<u8>], UInt8Type, new_from_opt_slice);
#[cfg(feature = "dtype-u16")]
impl_named_from!([Option<u16>], UInt16Type, new_from_opt_slice);
impl_named_from!([Option<u32>], UInt32Type, new_from_opt_slice);
impl_named_from!([Option<u64>], UInt64Type, new_from_opt_slice);
#[cfg(feature = "dtype-i8")]
impl_named_from!([Option<i8>], Int8Type, new_from_opt_slice);
#[cfg(feature = "dtype-i16")]
impl_named_from!([Option<i16>], Int16Type, new_from_opt_slice);
impl_named_from!([Option<i32>], Int32Type, new_from_opt_slice);
impl_named_from!([Option<i64>], Int64Type, new_from_opt_slice);
impl_named_from!([Option<f32>], Float32Type, new_from_opt_slice);
impl_named_from!([Option<f64>], Float64Type, new_from_opt_slice);

impl<T: AsRef<[Series]>> NamedFrom<T, ListType> for Series {
fn new(name: &str, s: T) -> Self {
let series_slice = s.as_ref();
let values_cap = series_slice.iter().fold(0, |acc, s| acc + s.len());

let dt = series_slice[0].dtype();
let mut builder = get_list_builder(dt, values_cap, series_slice.len(), name);
for series in series_slice {
builder.append_series(series)
}
builder.finish().into_series()
}
}

impl<T: AsRef<[Option<Series>]>> NamedFrom<T, [Option<Series>]> for Series {
fn new(name: &str, s: T) -> Self {
let series_slice = s.as_ref();
let values_cap = series_slice.iter().fold(0, |acc, opt_s| {
acc + opt_s.as_ref().map(|s| s.len()).unwrap_or(0)
});

let dt = series_slice
.iter()
.filter_map(|opt| opt.as_ref())
.next()
.expect("cannot create List Series from a slice of nulls")
.dtype();

let mut builder = get_list_builder(dt, values_cap, series_slice.len(), name);
for series in series_slice {
builder.append_opt_series(series.as_ref())
}
builder.finish().into_series()
}
}
3 changes: 2 additions & 1 deletion polars/polars-core/src/prelude.rs
Original file line number Diff line number Diff line change
Expand Up @@ -19,9 +19,10 @@ pub use crate::{
df,
error::{PolarsError, Result},
frame::{hash_join::JoinType, DataFrame},
named_from::NamedFrom,
series::{
arithmetic::{LhsNumOps, NumOpsDispatch},
IntoSeries, NamedFrom, Series, SeriesTrait,
IntoSeries, Series, SeriesTrait,
},
testing::*,
utils::IntoVec,
Expand Down
117 changes: 1 addition & 116 deletions polars/polars-core/src/series/from.rs
Original file line number Diff line number Diff line change
@@ -1,126 +1,11 @@
use crate::chunked_array::builder::get_list_builder;
use crate::chunked_array::cast::cast_chunks;
#[cfg(feature = "object")]
use crate::chunked_array::object::extension::polars_extension::PolarsExtension;
use crate::prelude::*;
use arrow::compute::cast::utf8_to_large_utf8;
use polars_arrow::compute::cast::cast;
use std::borrow::Cow;
use std::convert::TryFrom;

pub trait NamedFrom<T, Phantom: ?Sized> {
/// Initialize by name and values.
fn new(name: &str, _: T) -> Self;
}
//
macro_rules! impl_named_from {
($type:ty, $series_var:ident, $method:ident) => {
impl<T: AsRef<$type>> NamedFrom<T, $type> for Series {
fn new(name: &str, v: T) -> Self {
ChunkedArray::<$series_var>::$method(name, v.as_ref()).into_series()
}
}
};
}

impl<'a, T: AsRef<[&'a str]>> NamedFrom<T, [&'a str]> for Series {
fn new(name: &str, v: T) -> Self {
Utf8Chunked::new_from_slice(name, v.as_ref()).into_series()
}
}
impl<'a, T: AsRef<[Option<&'a str>]>> NamedFrom<T, [Option<&'a str>]> for Series {
fn new(name: &str, v: T) -> Self {
Utf8Chunked::new_from_opt_slice(name, v.as_ref()).into_series()
}
}

impl<'a, T: AsRef<[Cow<'a, str>]>> NamedFrom<T, [Cow<'a, str>]> for Series {
fn new(name: &str, v: T) -> Self {
Utf8Chunked::new_from_iter(name, v.as_ref().iter().map(|value| value.as_ref()))
.into_series()
}
}
impl<'a, T: AsRef<[Option<Cow<'a, str>>]>> NamedFrom<T, [Option<Cow<'a, str>>]> for Series {
fn new(name: &str, v: T) -> Self {
Utf8Chunked::new_from_opt_iter(
name,
v.as_ref()
.iter()
.map(|opt| opt.as_ref().map(|value| value.as_ref())),
)
.into_series()
}
}

impl_named_from!([String], Utf8Type, new_from_slice);
impl_named_from!([bool], BooleanType, new_from_slice);
#[cfg(feature = "dtype-u8")]
impl_named_from!([u8], UInt8Type, new_from_slice);
#[cfg(feature = "dtype-u16")]
impl_named_from!([u16], UInt16Type, new_from_slice);
impl_named_from!([u32], UInt32Type, new_from_slice);
impl_named_from!([u64], UInt64Type, new_from_slice);
#[cfg(feature = "dtype-i8")]
impl_named_from!([i8], Int8Type, new_from_slice);
#[cfg(feature = "dtype-i16")]
impl_named_from!([i16], Int16Type, new_from_slice);
impl_named_from!([i32], Int32Type, new_from_slice);
impl_named_from!([i64], Int64Type, new_from_slice);
impl_named_from!([f32], Float32Type, new_from_slice);
impl_named_from!([f64], Float64Type, new_from_slice);
impl_named_from!([Option<String>], Utf8Type, new_from_opt_slice);
impl_named_from!([Option<bool>], BooleanType, new_from_opt_slice);
#[cfg(feature = "dtype-u8")]
impl_named_from!([Option<u8>], UInt8Type, new_from_opt_slice);
#[cfg(feature = "dtype-u16")]
impl_named_from!([Option<u16>], UInt16Type, new_from_opt_slice);
impl_named_from!([Option<u32>], UInt32Type, new_from_opt_slice);
impl_named_from!([Option<u64>], UInt64Type, new_from_opt_slice);
#[cfg(feature = "dtype-i8")]
impl_named_from!([Option<i8>], Int8Type, new_from_opt_slice);
#[cfg(feature = "dtype-i16")]
impl_named_from!([Option<i16>], Int16Type, new_from_opt_slice);
impl_named_from!([Option<i32>], Int32Type, new_from_opt_slice);
impl_named_from!([Option<i64>], Int64Type, new_from_opt_slice);
impl_named_from!([Option<f32>], Float32Type, new_from_opt_slice);
impl_named_from!([Option<f64>], Float64Type, new_from_opt_slice);

impl<T: AsRef<[Series]>> NamedFrom<T, ListType> for Series {
fn new(name: &str, s: T) -> Self {
let series_slice = s.as_ref();
let values_cap = series_slice.iter().fold(0, |acc, s| acc + s.len());

let dt = series_slice[0].dtype();
let mut builder = get_list_builder(dt, values_cap, series_slice.len(), name);
for series in series_slice {
builder.append_series(series)
}
builder.finish().into_series()
}
}

impl<T: AsRef<[Option<Series>]>> NamedFrom<T, [Option<Series>]> for Series {
fn new(name: &str, s: T) -> Self {
let series_slice = s.as_ref();
let values_cap = series_slice.iter().fold(0, |acc, opt_s| {
acc + opt_s.as_ref().map(|s| s.len()).unwrap_or(0)
});

let dt = series_slice
.iter()
.filter_map(|opt| opt.as_ref())
.next()
.expect("cannot create List Series from a slice of nulls")
.dtype();

let mut builder = get_list_builder(dt, values_cap, series_slice.len(), name);
for series in series_slice {
builder.append_opt_series(series.as_ref())
}
builder.finish().into_series()
}
}

fn convert_list_inner(arr: &ArrayRef, fld: &ArrowField) -> ArrayRef {
// if inner type is Utf8, we need to convert that to large utf8
match fld.data_type() {
Expand All @@ -145,7 +30,7 @@ fn convert_list_inner(arr: &ArrayRef, fld: &ArrowField) -> ArrayRef {
}

// TODO: add types
impl std::convert::TryFrom<(&str, Vec<ArrayRef>)> for Series {
impl TryFrom<(&str, Vec<ArrayRef>)> for Series {
type Error = PolarsError;

fn try_from(name_arr: (&str, Vec<ArrayRef>)) -> Result<Self> {
Expand Down

0 comments on commit a512a3e

Please sign in to comment.