brassfibre 0.2.0

Provides multiple-dtype columner storage, known as DataFrame in pandas/R
Documentation
use num::{Num, Zero, ToPrimitive};
use std::borrow::{Borrow, Cow};
use std::hash::Hash;
use std::ops::{Add, Sub, Div};

use super::Block;
use algos::computation::{Aggregation, NanMinMax};
use indexer::Indexer;
use series::Series;
use traits::{Apply, BasicAggregation, NumericAggregation, ComparisonAggregation, Description};

impl<'v, 'i, 'c, V, I, C> BasicAggregation<'c> for Block<'v, 'i, 'c, V, I, C>
    where V: 'c + Clone + Zero + Add,
          I: Clone + Eq + Hash,
          C: 'c + Clone + Eq + Hash
{
    type Kept = Series<'c, 'c, V, C>;
    type Counted = Series<'c, 'c, usize, C>;

    fn sum(&'c self) -> Self::Kept {
        self.apply(&Aggregation::vec_sum)
    }

    fn count(&'c self) -> Self::Counted {
        self.apply(&Aggregation::vec_count)
    }
}

impl<'v, 'i, 'c, V, I, C> NumericAggregation<'c> for Block<'v, 'i, 'c, V, I, C>
    where V: 'c + Clone + Zero + Add + Sub + Div + ToPrimitive,
          I: Clone + Eq + Hash,
          C: 'c + Clone + Eq + Hash
{
    type Coerced = Series<'c, 'c, f64, C>;

    fn mean(&'c self) -> Self::Coerced {
        self.apply(&Aggregation::vec_mean)
    }

    fn var(&'c self) -> Self::Coerced {
        self.apply(&Aggregation::vec_var)
    }

    fn unbiased_var(&'c self) -> Self::Coerced {
        self.apply(&Aggregation::vec_unbiased_var)
    }

    fn std(&'c self) -> Self::Coerced {
        self.apply(&Aggregation::vec_std)
    }

    fn unbiased_std(&'c self) -> Self::Coerced {
        self.apply(&Aggregation::vec_unbiased_std)
    }
}

impl<'v, 'i, 'c, V, I, C> ComparisonAggregation<'c> for Block<'v, 'i, 'c, V, I, C>
    where V: 'c + Clone + NanMinMax<V>,
          I: Clone + Eq + Hash,
          C: Clone + Eq + Hash
{
    type Kept = Series<'c, 'c, V, C>;

    fn min(&'c self) -> Self::Kept {
        self.apply(&Aggregation::vec_min)
    }

    fn max(&'c self) -> Self::Kept {
        self.apply(&Aggregation::vec_max)
    }
}

impl<'v, 'i, 'c, V, I, C> Description<'c> for Block<'v, 'i, 'c, V, I, C>
    where V: 'c + Clone + Zero + Add + Sub + Div + ToPrimitive + NanMinMax<V>,
          I: Clone + Eq + Hash,
          C: Clone + Eq + Hash
{
    type Described = Block<'c, 'c, 'c, f64, &'c str, C>;

    fn describe(&'c self) -> Self::Described {
        let new_index: Vec<&str> = vec!["count", "mean", "std", "min", "max"];

        let describe = |x: &Vec<V>| {
            vec![Aggregation::vec_count(x) as f64,
                 Aggregation::vec_mean(x),
                 Aggregation::vec_std(x),
                 ToPrimitive::to_f64(&Aggregation::vec_min(x)).unwrap(),
                 ToPrimitive::to_f64(&Aggregation::vec_max(x)).unwrap()]
        };
        let new_values: Vec<Cow<Vec<f64>>> = self.values
            .iter()
            .map(|x| Cow::Owned(describe(x)))
            .collect();
        Block::from_cow(new_values,
                        Cow::Owned(Indexer::new(new_index)),
                        Cow::Borrowed(self.columns.borrow()))
    }
}