6

さまざまな型を含む箱入り行列があるとします。

matrix =: ('abc';'defgh';23),:('foo';'bar';45)
matrix
+---+-----+--+
|abc|defgh|23|
+---+-----+--+
|foo|バー |45|
+---+-----+--+

そして列記述子:

columnTypes =: 'string';'string';'num'

タイプに応じて、列ごとにこのマトリックスに動詞を適用したいと考えています。動詞 DoString と DoNum を使用します。

chain =: (('string';'num') i. columnTypes) { DoString`DoNum

編集: 列記述子は重要です。使用する動詞の決定は、型自体ではなく、それらに基づいて行われます。実際には、いくつかのタイプの文字列、数値、さらには日付 (J では数値) を使用できます。

chainの各行に適用するにはどうすればよいmatrixですか? 動詞自体は、渡された値がボックス化されているかどうかを処理できます。それで問題ありません。|:また、行列 ( ) は非常に大きくなる可能性があるため、転置は避けたいと思います。

4

3 に答える 3

5

これを行う標準的な方法は次のとおりです。

  1. 行 (セル) 指向の構造を列指向の構造に変換する

  2. 各列に正しい動詞を適用する (1 回だけ)

手順 (1) は簡単です。ステップ (2) も簡単ですが、それほど明白ではありません。役立つちょっとしたトリックがあります。

秘訣は、多くのプリミティブ演算子が動名詞を左引数として受け入れ、動名詞を巡回して各動詞を順番に適用する関数を生成することを知っていることです。IMO、このカテゴリで最も便利な演算子は です;. 。これを使用した実装例を次に示します。

ステップ (0)、入力:

   matrix      =:  ('abc';'defgh';23),:('foo';'bar';45)

   columnTypes =:  'string';'string';'num'

   DoString    =:  toupper
   DoNum       =:  0&j.

   matrix
+---+-----+--+
|abc|defgh|23|
+---+-----+--+
|foo|bar  |45|
+---+-----+--+

ステップ (1)、データの整理:

   columnify   =:  <@:>"1@:|: :. rowify =: <"_1&>
   columnify matrix
+---+-----+-----+
|abc|defgh|23 45|
|foo|bar  |     |
+---+-----+-----+

columnify には、データを再「rowify」する逆関数が用意されていることに注意してください。ただし、これを行うべきではありません。以下を参照してください。

ステップ (2) の動詞循環機能を使用して、正しい動詞を各列に (正確に 1 回) 適用します;.

   homogenize  =:  ({. foo&.>@:{.`'') [^:('foo'-:])L:0~ ]
   chain       =:  DoString`DoNum`] homogenize@{~  ('string';'num')&i.  

不明な列タイプのデフォルトの変換は恒等関数であることに注意してください]

動詞homogenizeは、各列プロセッサの入力と出力を正規化します (つまり、ユーザーが変換の動的な「コア」のみを提供する必要があるように、前処理と後処理を抽象化します)。この動詞は、入力として列タイプのリストを取り、 (または同様の演算子)chainの左側の引数を使用するのに適した動名詞を導出します。;.

したがって:

   1 (chain columnTypes);.1  columnify matrix
+---+-----+---------+
|ABC|DEFGH|0j23 0j45|
|FOO|BAR  |         |
+---+-----+---------+

または、ボックス化されたセルの NxM テーブルが本当に必要な場合は、列化の「下」にカットを適用します。

   1 (chain columnTypes);.1&.columnify matrix
+-----+-----+
|ABC  |FOO  |
+-----+-----+
|DEFGH|BAR  |
+-----+-----+
|0j23 |0j45 |
+-----+-----+

ただし、J コンテキストでは、パフォーマンスと表記上の理由から、テーブルを同種の列のリストとして保持する方がはるかに適切であることに注意してください。

J は、配列を「まとめて」処理する場合に最適に機能します。経験則として、各アプリケーションでプリミティブまたはユーザー定義の名前にできるだけ多くのデータを表示させる必要があります。これが、この「列化」アプローチの主な利点です。データを同種の列のリストとして保存すると、後で操作するのが速くなり、簡単になります。

ただし、ユースケースで、ボックス化されたセルの NxM テーブルとしてデータを保持することが本当に必要な場合は、データを列の標準形式に変換したり、列の標準形式から変換したりするのは、費用がかかります。その場合、元のソリューションに固執する必要があります。

   1 chain\"1 matrix

;.これは(あなたが尋ねたため)実際にはアプローチと同じ前提で機能します。特に、\動名詞引数を受け入れ、各動詞を連続して適用する (つまり、データの新しいウィンドウごとに周期的に適用する) 原始演算子の 1 つです。

実際に1 chain\"1 matrixは、行列を行 ( "1) に分割し、行ごとに 1 幅の移動ウィンドウ ( 1 f\ matrix) を作成し、これらの 1 幅のウィンドウのそれぞれに動詞を周期的に適用しchainます (つまりf、1 ごとに変化します)。 -行列の各行のデータ ウィンドウ全体)。

行の移動する 1-window (rank-1 ベクトル) は行のアトムであり、順序どおりであり、の動詞はchain同じ順序で与えられるため、実際には、これらの動詞をの列に適用しています。マトリックス、1つ。原子。で。を。時間。

要するに: 1 chain\"1 matrixは に似ていますがfoo"0 matrix、foo はアトムごとに変更されます。また、一般的に回避する必要があるのと同じ理由で、これを回避する必要がありfoo"0 matrixます。小さなランクで関数を適用すると、J の粒度に反して動作し、パフォーマンスが低下するためです。

一般に、可能な限り高いランクで適用関数を使用することをお勧めします。この場合、matrix列の正規形に変換 (および維持) する必要があります。

言い換えれば、ここで;."1そのまま\です"0columnify/の全体がhomogenize( と比較して) 長すぎたりかさばったり1 chain\"1 matrixする場合は、[1] で提供されているスクリプトをインポートできます。これは、これらの定義を拡張機能付きの再利用可能なユーティリティとしてパッケージ化したものです。例と手順については、ページを参照してください。

[1] 関連ユーティリティ スクリプト:
http://www.jsoftware.com/jwiki/DanBron/Snippets/DOOG

于 2013-07-08T22:17:44.120 に答える
2

これらの計算が個々のボックス内のデータ (およびおそらくグローバル値) のみに依存する場合、Under Open (別名 Each) で Agenda を使用することができます。この手法のアプリケーションを以下に示します。

   doCells  =: (doNum`doString @. isLiteral)&.>
   isLiteral=: 2 -: 3!:0

   doNum    =: +:   NB. Double
   doString =: toupper

   doCells matrix
┌───┬─────┬──┐
│ABC│DEFGH│46│
├───┼─────┼──┤
│FOO│BAR  │90│
└───┴─────┴──┘

doNum(この例では、実行可能性をわかりやすくするために、 とに恣意的な意味を入れていdoStringます。)

ここで使用されている のバージョンでisLiteral十分かもしれませんが、スパース リテラルまたは Unicode 値が含まれる場合は失敗します。

計算に単一のボックスよりも多くのマトリックスを含める必要がある場合、これはあなたの質問に対する答えにはなりません。計算を行単位で行う必要がある場合は、ランク _1 の動詞を (つまり、最高軸の各項目に) 適用することで解決できます。

于 2011-08-02T17:10:02.027 に答える
0

実験を通して、私はこれを私がやりたいことをするようにしました:

1 chain\"1 matrix

今それを理解するために...

于 2011-08-03T02:41:41.000 に答える