use csv;
use std::hash::Hash;
use std::io::{Read, Write};
use std::string::ToString;
use nullvec::prelude::{Array, Scalar};
use frame::DataFrame;
use indexer::Indexer;
use traits::{Slicer, RowIndex};
fn default_columns(n: usize) -> Vec<String> {
let columns: Vec<usize> = (0..n).collect();
columns.into_iter().map(|x| x.to_string()).collect()
}
impl<'a, I, C> DataFrame<'a, 'a, 'a, I, C>
where I: Clone + Eq + Hash,
C: Clone + Eq + Hash
{
pub fn read_csv<R: Read>(mut reader: csv::Reader<R>)
-> Result<DataFrame<'a, 'a, 'a, usize, String>, csv::Error> {
let header: Vec<String> = try!(reader.headers());
let columns: Vec<String> = if reader.has_headers {
header
} else {
default_columns(header.len())
};
let ncols = columns.len();
let mut records: Vec<Vec<Scalar>> = vec![];
for record in reader.decode() {
let values: Vec<Scalar> = try!(record);
records.push(values);
}
let index: Indexer<usize> = Indexer::<usize>::from_len(records.len());
let mut colvecs: Vec<Vec<Scalar>> = Vec::with_capacity(ncols);
for _ in 0..columns.len() {
colvecs.push(Vec::with_capacity(records.len()));
}
for record in records {
for (column, val) in colvecs.iter_mut().zip(record) {
column.push(val);
}
}
let mut arrays: Vec<Array> = Vec::with_capacity(ncols);
for column in colvecs {
let array: Array = column.into();
arrays.push(array);
}
Ok(DataFrame::from_vec(arrays, index, columns))
}
}
impl<'a, I, C> DataFrame<'a, 'a, 'a, I, C>
where I: Clone + Eq + Hash,
C: Clone + Eq + Hash + ToString
{
pub fn write_csv<W: Write>(&self, writer: &mut csv::Writer<W>) -> Result<(), csv::Error> {
let mut columns: Vec<Scalar> = Vec::with_capacity(self.values.len() + 1);
for i in self.columns.values.iter() {
let s: Scalar = i.to_string().into();
columns.push(s);
}
try!(writer.encode(columns));
for i in 0..self.len() {
let mut row: Vec<Scalar> = Vec::with_capacity(self.values.len() + 1);
for col in self.values.iter() {
row.push(col.iloc(&i));
}
try!(writer.encode(row));
}
Ok(())
}
}