Deedle: .NET用の探索的データライブラリ

Deedleはデータおよび時系列操作、あるいは科学計算プログラミング用のライブラリで簡単に使用できます。 このライブラリは構造的データフレーム処理、整列済みあるいは未成列データ処理、時系列データ処理を サポートしています。DeedleはF#やC#のインタラクティブコンソールを使用して行う 手探りのプログラミングに適するよう設計されていますが、コンパイル済みの.NETコードにおいても 活用できます。
ライブラリには複雑なインデクシングやスライシング、データの連結やアライメント、 値の無いデータに対する処理、グループ化や集計、統計など、多岐にわたるデータ操作が実装されています。
タイタニック号の生存者を20行のコードで分析する
タイタニック号のデータセット を
titanic
という名前のデータフレームとして読み込んであるとします
(このデータフレームにはint型のPclass
やbool型のSurvived
といった多数の列があります)。
そして乗船券の階級別に生存者の比率を計算してみましょう:
1: 2: 3: 4: 5: 6: 7: 8: 9: 10: 11: 12: 13: 14: 15: 16: 17: 18: 19: 20: |
// タイタニック号のデータを読み込み、「性別」でグループ化します let titanic = Frame.ReadCsv(root + "titanic.csv").GroupRowsBy<int>("Pclass") // 'Survived'列を取得して階級毎の生存者集を計算します let byClass = titanic.GetColumn<bool>("Survived") |> Series.applyLevel fst (fun s -> // 'Survived'が'True'と'False'のデータを取得します series (Seq.countBy id s.Values)) // 'Pclass'を行、'Died' と 'Survived' を列に持つようなフレームを作成します |> Frame.ofRows |> Frame.sortRowsByKey |> Frame.indexColsWith ["Died"; "Survived"] // タイタニック号の男性および女性の総数を持つ列を追加します byClass?Total <- byClass?Died + byClass?Survived // 結果をいい感じにパーセント表示するようなデータフレームを組み立てます frame [ "死者 (%)" => round (byClass?Died / byClass?Total * 100.0) "生存者 (%)" => round (byClass?Survived / byClass?Total * 100.0) ] |
死者 (%) |
生存者 (%) |
|
---|---|---|
1 |
37 |
63 |
2 |
53 |
47 |
3 |
76 |
24 |
ここではまずデータをPclass
でグループ化して、Survived
列をブール値のシリーズとして取得しています。
そしてapplyLevel
を使用して各グループにまとめています。
この関数は旅行者の階級毎に特定の関数を呼び出します。
今回は生存者数と死者数をカウントしています。
そして適切なラベルを付けてフレームをソートし、
いい感じのまとめとなるような新しいデータフレームを組み立てています。
Deedleの取得方法
ライブラリは NuGetのDeedleサイト からダウンロードできます。 また GitHub上のソースコード を取得したり、 ソースコードをZIPファイルとしてダウンロード することもできます。 コンパイル済みのバイナリをZIPファイルとしてダウンロード することもできます。
DeedleとF# Data、R 型プロバイダー、あるいはその他のF#製データサイエンスコンポーネントとを組み合わせたいのであれば、 FsLab パッケージ を検討してみるとよいでしょう。 Visual Studioを使用しているのであれば FsLab プロジェクトテンプレート をインストールすることもおすすめです。
サンプルとドキュメント
ライブラリには包括的なドキュメントが欠かせません。
チュートリアルや記事はいずれも samplesフォルダ 内の
*.fsx
ファイルから自動生成されています。
また、ライブラリの実装コードに記述されたMarkdownコメントを元にして、
APIリファレンスも自動生成されています。
クイックスタートチュートリアル ではF#データライブラリの 主要な機能の用法を紹介しています。 まずはこちらから始めましょう。 10分ほどでライブラリの用法を学習できます。
データフレームの機能 には一般的に使用されるデータフレームの機能について、 さらに多くの例があります。 たとえばスライシングや連結、グループ化、集計といった機能があります。
シリーズの機能 では(株価のような)時系列データを処理する際に 使用される機能について詳しく説明します。 たとえばスライディングウィンドウやチャンク化、サンプリングや統計といった機能があります。
フレームおよびシリーズ統計の計算 では平均や分散、歪度などの統計指針を 計算する方法について説明します。 またこのチュートリアルではウィンドウの移動やウィンドウ統計の拡張も行います。
DeedleライブラリはF#とC#いずれにおいても使用できます。 なるべくそれぞれの言語に倣ったAPIとなるようにしています。 C#フレンドリーなAPIについては DeedleをC#から使用する の ページを参照してください。
ライブラリ内にあるすべての型やモジュール、関数から自動生成されたドキュメントが APIリファレンス にあります。 また、すべてがドキュメント化されている主要なモジュールは以下の3つです:
Series
モジュール には 各データシリーズや時系列の値を処理するための機能があります。Frame
モジュール にはSeries
モジュールと似た機能が多数ありますが、いずれもデータフレーム全体を対象とするものです。Stats
モジュール には 標準的な統計関数やウィンドウの移動など、多数の機能があります。 このモジュールにはシリーズとフレーム両方を対象とする関数があります。
貢献方法および著作権
プロジェクトはGitHub 上でホストされており、 Issuesの報告 やプロジェクトのフォーク、プルリクエストの送信などを行うことができます。 公開用のAPIを新規に追加する場合はドキュメントとなるような サンプル も 合わせて追加するようにしてください。 ライブラリの動作については ライブラリの設計メモ を参照されるとよいでしょう。
F# とデータサイエンスに関する一般的な話題に興味があるのであれば、 F# data science and machine learning ワーキンググループに参加してみるとよいでしょう。 ここではF#用のデータサイエンスプロジェクトに関する活動を行っています。
ライブラリは BlueMountain Capital ならびに 共著者によって開発されています。 ライセンスはBSD ライセンスを採用しているため、 商用非商用問わず、変更および再配布することができます。 詳細についてはGitHubレポジトリの ライセンスファイル を参照してください。
Full name: Index.titanic
module Frame
from Deedle
--------------------
type Frame =
static member CreateEmpty : unit -> Frame<'R,'C> (requires equality and equality)
static member FromArray2D : array:'T [,] -> Frame<int,int>
static member FromColumns : cols:Series<'TColKey,Series<'TRowKey,'V>> -> Frame<'TRowKey,'TColKey> (requires equality and equality)
static member FromColumns : cols:Series<'TColKey,ObjectSeries<'TRowKey>> -> Frame<'TRowKey,'TColKey> (requires equality and equality)
static member FromColumns : columns:seq<KeyValuePair<'ColKey,ObjectSeries<'RowKey>>> -> Frame<'RowKey,'ColKey> (requires equality and equality)
static member FromColumns : columns:seq<KeyValuePair<'ColKey,Series<'RowKey,'V>>> -> Frame<'RowKey,'ColKey> (requires equality and equality)
static member FromColumns : rows:seq<Series<'ColKey,'V>> -> Frame<'ColKey,int> (requires equality)
static member FromRecords : values:seq<'T> -> Frame<int,string>
static member FromRecords : series:Series<'K,'R> -> Frame<'K,string> (requires equality)
static member FromRowKeys : keys:seq<'K> -> Frame<'K,string> (requires equality)
...
Full name: Deedle.Frame
--------------------
type Frame<'TRowKey,'TColumnKey (requires equality and equality)> =
interface IDynamicMetaObjectProvider
interface INotifyCollectionChanged
interface IFsiFormattable
interface IFrame
new : names:seq<'TColumnKey> * columns:seq<ISeries<'TRowKey>> -> Frame<'TRowKey,'TColumnKey>
private new : rowIndex:IIndex<'TRowKey> * columnIndex:IIndex<'TColumnKey> * data:IVector<IVector> -> Frame<'TRowKey,'TColumnKey>
member AddColumn : column:'TColumnKey * series:ISeries<'TRowKey> -> unit
member AddColumn : column:'TColumnKey * series:seq<'V> -> unit
member AddColumn : column:'TColumnKey * series:ISeries<'TRowKey> * lookup:Lookup -> unit
member AddColumn : column:'TColumnKey * series:seq<'V> * lookup:Lookup -> unit
...
Full name: Deedle.Frame<_,_>
--------------------
new : names:seq<'TColumnKey> * columns:seq<ISeries<'TRowKey>> -> Frame<'TRowKey,'TColumnKey>
static member Frame.ReadCsv : stream:IO.Stream * ?hasHeaders:bool * ?inferTypes:bool * ?inferRows:int * ?schema:string * ?separators:string * ?culture:string * ?maxRows:int -> Frame<int,string>
Full name: Index.root
val int : value:'T -> int (requires member op_Explicit)
Full name: Microsoft.FSharp.Core.Operators.int
--------------------
type int = int32
Full name: Microsoft.FSharp.Core.int
--------------------
type int<'Measure> = int
Full name: Microsoft.FSharp.Core.int<_>
Full name: Index.byClass
member Frame.GetColumn : column:'TColumnKey * lookup:Lookup -> Series<'TRowKey,'R>
Full name: Microsoft.FSharp.Core.bool
module Series
from Deedle
--------------------
type Series =
static member ofNullables : values:seq<Nullable<'a0>> -> Series<int,'a0> (requires default constructor and value type and 'a0 :> ValueType)
static member ofObservations : observations:seq<'a0 * 'a1> -> Series<'a0,'a1> (requires equality)
static member ofOptionalObservations : observations:seq<'K * 'a1 option> -> Series<'K,'a1> (requires equality)
static member ofValues : values:seq<'a0> -> Series<int,'a0>
Full name: Deedle.FSharpSeriesExtensions.Series
--------------------
type Series<'K,'V (requires equality)> =
interface IFsiFormattable
interface ISeries<'K>
new : pairs:seq<KeyValuePair<'K,'V>> -> Series<'K,'V>
new : keys:seq<'K> * values:seq<'V> -> Series<'K,'V>
new : index:IIndex<'K> * vector:IVector<'V> * vectorBuilder:IVectorBuilder * indexBuilder:IIndexBuilder -> Series<'K,'V>
member After : lowerExclusive:'K -> Series<'K,'V>
member Aggregate : aggregation:Aggregation<'K> * observationSelector:Func<DataSegment<Series<'K,'V>>,KeyValuePair<'TNewKey,OptionalValue<'R>>> -> Series<'TNewKey,'R> (requires equality)
member Aggregate : aggregation:Aggregation<'K> * keySelector:Func<DataSegment<Series<'K,'V>>,'TNewKey> * valueSelector:Func<DataSegment<Series<'K,'V>>,OptionalValue<'R>> -> Series<'TNewKey,'R> (requires equality)
member AsyncMaterialize : unit -> Async<Series<'K,'V>>
member Before : upperExclusive:'K -> Series<'K,'V>
...
Full name: Deedle.Series<_,_>
--------------------
new : pairs:seq<Collections.Generic.KeyValuePair<'K,'V>> -> Series<'K,'V>
new : keys:seq<'K> * values:seq<'V> -> Series<'K,'V>
new : index:Indices.IIndex<'K> * vector:IVector<'V> * vectorBuilder:Vectors.IVectorBuilder * indexBuilder:Indices.IIndexBuilder -> Series<'K,'V>
Full name: Deedle.Series.applyLevel
Full name: Microsoft.FSharp.Core.Operators.fst
Full name: Deedle.FSharpSeriesExtensions.series
from Microsoft.FSharp.Collections
Full name: Microsoft.FSharp.Collections.Seq.countBy
Full name: Microsoft.FSharp.Core.Operators.id
static member Frame.ofRows : rows:Series<'a0,#ISeries<'a2>> -> Frame<'a0,'a2> (requires equality and equality)
Full name: Deedle.Frame.sortRowsByKey
Full name: Deedle.Frame.indexColsWith
Full name: Deedle.FSharpFrameExtensions.frame
Full name: Microsoft.FSharp.Core.Operators.round