[][src]Struct tubular::DataFrame

pub struct DataFrame { /* fields omitted */ }

A 2D matrix of cells of mixed types useful for exploratory data analysis.

Basic Concept

A DataFrame consists of 0 or more Columns in a specific order. The DataFrame keeps track of a Header associated with each of its columns. The Header can be used to display the whole DataFrame or it can be used to lookup a single Column.

Rows can be constructed by gathering up one cell from all columns at the same position. Since Rows are composed of many possibly different types, in the normal case, each cell in the column is of a different type which can't be known until runtime. Tubular tries to make this as ergonomic as possible, but working with Rows will always be a bit more ceremonius than working with Columns.

Here's how to think about the structure of a DataFrame:

DataFrame

 + - - - -+- - - - + - - - -+
 | Header | Header | Header |
 + - - - -+- - - - + - - - -+
 | Column | Column | Column |
 |  bool  |  u32   | String |
 | ------ | ------ | ------ |
 | |cell| | |cell| | |cell| |
 | ------ | ------ | ------ |
 | |cell| | |cell| | |cell| |
 | ------ | ------ | ------ |
 | ================================
 | |cell|   |cell|   |cell  | Row |
 | |bool|   |u32 |   |String|     |
 | ================================
 | ------ | ------ | ------ |
 | |cell| | |cell| | |cell| |
 | ------ | ------ | ------ |
 + - - - -+- - - - + - - - -+

Constructing a DataFrame

DataFrame implements Default, which is generally the easiest way to create one from scratch:

use tubular::DataFrame;

let df = DataFrame::default();

To add columns, use push():

df.push("Fruits", &["apple", "banana", "pear"]);

Although you could try using Serde to load a DataFrame, the current implementation is very basic and not likely to work as you expect.

Exploring

The easiest way to figure out what's in a DataFrame is to print it out:

println!("{}", &df);

The result will be a table looking something like this:

Fruits Organic Quantity
 apple    true       16
banana   false       30
  pear    true       10

Iteration

DataFrames can be used in for loops to iterate one column at a time:

for column in &df {
    println!("{:?}", column);
}

Methods

impl DataFrame[src]

pub fn push(&mut self, header: impl Into<Header>, column: impl Into<Column>)[src]

Adds a new Column to the end of the DataFrame.

Any iterator over items that implement ColumnType can be passed as argument for the new column:

use tubular::DataFrame;
use std::sync::mpsc::channel;
use std::thread;

let mut df = DataFrame::default();

// Add normal "list"-like iterators to a DataFrame
df.push("Fruits", &["apple", "banana", "pear"]);
df.push("Organic", vec![true, false, true]);
df.push("Quantity", [16, 30, 10].iter());

// Or other less obvious sequences
df.push("Sku", 1..4);
df.push("Log Lines", "192.12.78.1 - 200\n25.31.197.245 - 200\n78.95.83.123 - 304".lines());
df.push("Words", "abc1def2ghi".split(char::is_numeric));

// ...Or real crazy iterators
let (sender, recv) = channel();
thread::spawn(move || {
    sender.send(10.3).unwrap();
    sender.send(97.2).unwrap();
    sender.send(-15.3).unwrap();
});
df.push("Temperatures", recv);

pub fn len(&self) -> usize[src]

Returns the number of Columns in the DataFrame

use tubular::DataFrame;
let mut df = DataFrame::default();
df.push("Words", "abc1def2ghi".split(char::is_numeric));
assert_eq!(df.len(), 1);

pub fn headers(&self) -> &Vec<Header>[src]

Provides all the headers

use tubular::DataFrame;
let mut df = DataFrame::default();
df.push("Fruits", &["apple", "banana", "pear"]);
df.push("Organic", &[true, false, true]);
df.push("Quantity", &[16, 30, 10]);
assert_eq!(df.headers(), &vec![
    "Fruits".to_string(),
    "Organic".to_string(),
    "Quantity".to_string()
]);

pub fn row_len(&self) -> usize[src]

Returns the number of rows in the DataFrame.

NOTE: This method is unstable is likely to be removed or changed semantically in the near future.

pub fn rows(&self) -> Rows[src]

Allows iteration over Row objects

use tubular::DataFrame;
let mut df = DataFrame::default();
df.push("Fruits", &["apple"]);
df.push("Organic", &[true]);
df.push("Quantity", &[16]);
for row in df.rows() {
    assert_eq!(row.column_name::<String>("Fruits"), "apple");
    assert_eq!(row.column_name::<bool>("Organic"), &true);
    assert_eq!(row.column_name::<i32>("Quantity"), &16);
}

Trait Implementations

impl Clone for DataFrame[src]

impl Debug for DataFrame[src]

impl Default for DataFrame[src]

impl Display for DataFrame[src]

impl<'d> From<&'d DataFrame> for Rows<'d>[src]

impl Index<&'static str> for DataFrame[src]

type Output = Column

The returned type after indexing.

impl Index<String> for DataFrame[src]

type Output = Column

The returned type after indexing.

impl Index<usize> for DataFrame[src]

type Output = Column

The returned type after indexing.

impl<'d> IntoIterator for &'d DataFrame[src]

type IntoIter = IntoIter<'d>

Which kind of iterator are we turning this into?

type Item = Column

The type of the elements being iterated over.

impl PartialEq<DataFrame> for DataFrame[src]

impl StructuralPartialEq for DataFrame[src]

Auto Trait Implementations

Blanket Implementations

impl<T> Any for T where
    T: 'static + ?Sized
[src]

impl<T> Borrow<T> for T where
    T: ?Sized
[src]

impl<T> BorrowMut<T> for T where
    T: ?Sized
[src]

impl<T> From<T> for T[src]

impl<T, U> Into<U> for T where
    U: From<T>, 
[src]

impl<T> ToOwned for T where
    T: Clone
[src]

type Owned = T

The resulting type after obtaining ownership.

impl<T> ToString for T where
    T: Display + ?Sized
[src]

impl<T, U> TryFrom<U> for T where
    U: Into<T>, 
[src]

type Error = Infallible

The type returned in the event of a conversion error.

impl<T, U> TryInto<U> for T where
    U: TryFrom<T>, 
[src]

type Error = <U as TryFrom<T>>::Error

The type returned in the event of a conversion error.