Rust csv をtupleでindex column(1列目)をわけてdesrerializeする

tupleでindex column(1列目)をわけてdesrerializeする

 

 

```.rust

extern crate csv;
#[macro_use]
extern crate serde_derive;

use csv::ReaderBuilder;
use std::error::Error;

#[derive(Debug, Deserialize, Eq, PartialEq)]
struct Row {
    value: Vec<i32>,
}

fn example() -> Result<(), Box<dyn Error>> {
    let data = "\
label,value1,value2
l1,2,4
l2,2,4
";
    let mut rdr = ReaderBuilder::new()
        .has_headers(false)
        .from_reader(data.as_bytes());
    // skip since header 1
    let mut data = rdr.deserialize().skip(1).collect::<Result<Vec<(String, Row)>, _>>().unwrap();
    for row in data{
        println!("label: {:?}", row.0);    
        println!("data: {:?}", row.1);  
    }
    
    Ok(())
}

fn main() {
    example();
}

```

環境に最もやさしいプログラミング言語はC。Rustは2位

コンピュータの消費電力とプログラミング言語の選択に相関関係があるかどうか。ポルトガルの大学の研究者グループがそうした疑問に応える論文を発表した。

タイトルは「Energy Efficiency across Programming Languages / How Do Energy, Time, and Memory Relate? 」。

 

この論文は、27の有名なソフトウエア言語のランタイム、メモリ使用量、エネルギー消費量に関する研究を紹介する。各言語で表現された10種類のプログラミング問題を用いて、これらの言語の性能を監視した。その結果、消費電力が少ない言語と多い言語、メモリ使用量が消費電力に与える影響など、興味深い知見が得られた。この結果を用いて、ソフトウェア技術者がエネルギー効率を重視する場合に、どの言語を使用するかを決定するための支援を提供する方法を示す。

選択されたプログラミング言語が「よく知られている」ものであることについては問題があるかもしれませんが、このプロジェクトは非常に綿密で、文書化もかなり進んでいます。多くの人は、高速に動作するコンピュータ・プログラムほど消費電力が少ないことを当然と考えるだろう。しかし、電力消費の方程式には速度以外の要素も含まれるため、必ずしもそうとは限りません。研究チームは、Computer Language Benchmarks Gameプロジェクト(旧称:The Great Computer Language Shootout)の標準アルゴリズム10個を評価基準として使用した。

 

f:id:realitytoabstract:20220123183510p:plain

プログラミング言語別エネルギー使用量



 

Rustでcsv deserialize してstruct配列を取得する

deserializeはcsv::DeserializeRecordsIterを返却するので、collectすると取得できる。

型を指定してcollectしないと

consider specifying the type argument in the method call

のエラーが出る。

extern crate csv;
#[macro_use]
extern crate serde_derive;

use csv::ReaderBuilder;
use std::error::Error;

#[derive(Debug, Deserialize, Eq, PartialEq)]
struct Row {
    label: String,
    value: Vec<i32>,
}

fn example() -> Result<(), Box<dyn Error>> {
    let data = "\
label,value1,value2
l1,2,4
l2,2,4
";
    let mut rdr = ReaderBuilder::new()
        .has_headers(false)
        .from_reader(data.as_bytes());
    // skip since header 1
    let mut data = rdr.deserialize().skip(1).collect::<Result<Vec<(Row)>, _>>().unwrap();
    println!("{:?}", data);
    Ok(())
}

fn main() {
    example();
}

headerを無視して、deserialize したい場合。 (has_headers falseでskip)

headerを無視して、deserialize したい場合がある。

label,value1,value2
l1,2,4
l2,2,4

で、structは

#[derive(Debug, Deserialize, Eq, PartialEq)]
struct Row {
    label: String,
    value: Vec<i32>,
}

みたいなケースだ。 こういうときはskipを使ってheaderを無視する

extern crate csv;
#[macro_use]
extern crate serde_derive;

use csv::ReaderBuilder;
use std::error::Error;

#[derive(Debug, Deserialize, Eq, PartialEq)]
struct Row {
    label: String,
    value: Vec<i32>,
}

fn example() -> Result<(), Box<dyn Error>> {
    let data = "\
label,value1,value2
l1,2,4
l2,2,4
";
    let mut rdr = ReaderBuilder::new()
        .has_headers(false)
        .from_reader(data.as_bytes());
    // skip since header 1
    let mut iter = rdr.deserialize().skip(1);
    for result in iter {
        let record: Row = result?;
        println!("{:?}", record);
    }
    Ok(())
}

fn main() {
    example();
}

while と loop なぜ二つあるのか 、while trueではだめなのか

while trueとloopの違いはあるが、現段階では理解することはあまり重要ではないとRustチュートリアルにはあるが、どのような違いがあるか?をここで解説する。

http://web.mit.edu/rust-lang_v1.25/arch/amd64_ubuntu1404/share/doc/rust/html/book/first-edition/loops.html

無限ループが必要なとき

while true {

を使いたいかもしれないが、

loopを使ったほうが良いだろう

loop {

Rustのコントロールフロー解析では、この構文は常にループすることが分かっているので、while trueとは異なる扱いをするためだ。一般に、コンパイラに与える情報が多ければ多いほど、安全性とコード生成の面で有利になる。したがって、無限にループする予定がある場合は、常にloopを選択すべきだ。

上の説明だと、いまいち抽象的でよくわからないが、実際whileだとうまく動かないケースをみてみよう。

while は以下のコードで初期化エラーをはく。

let x;
while true { x ="hogehoge"; break; }
println!("{}", x);

while trueは必ず実行されるのでxは初期化されるが、コンパイラはwhile文内が一度は必ず実行されることを考慮して型推測をしてくれない。

一方loopを使うと

let x;
loop { x ="hogehoge"; break; }
println!("{}", x)

コンパイルすることができる。

rust で 行列のaxisごとのsumをする

行列を仮定してます

方針は 行はシンプルでmap trickを使ってsumする。最後にcollect が必要です

列sumはtransposeseしてからsumする

本格的にnumpy的なことをしたいならndarray的なのを使おう

use rayon::prelude::*;

pub fn transpose<T: Send + Sync + Copy  >(v: &Vec<Vec<T>>) -> Vec<Vec<T>> {
    assert!(!v.is_empty());
    let len = v[0].len();
    (0..len).into_par_iter()
        .map(|i| v.iter().map(|row| row[i]).collect())
        .collect()
}


fn main() {
    let v = vec![vec![1, 2,3], vec![3, 4,6]];
    let vt  = transpose(&v);
    println!("{:?}",v);
    let vs:Vec<i32> = v.iter().map(|row| row.iter().sum() ).collect();
    println!("{:?}",vs);
    println!("{:?}",vt);
    let vt_s:Vec<i32>  = vt.iter().map(|row| row.iter().sum() ).collect();
    
    println!("{:?}",vt_s);
}