for ループを使用しないリストのリストの転置for ループを使用せずにリストのリストを転置する方法が必要です。 つまり、次のように、リストのリストの「行」と「列」を反転する関数 (たとえば、「Listtranspose」と呼びます) です。
listlist = {{"cat", "dog", "mouse"}, {"meow", "bark", "squeak"}};
tranlist = Listtranspose(listlist);
Show(tranlist);
/*Result:
{{"cat", "meow"}, {"dog", "bark"}, {"mouse", "squeak}}
代替実装は次のようになります。
listlist = {{"cat", "dog", "mouse"}, {"meow", "bark", "squeak"}};
nr = NItems(listlist);
col1 = listlist[1::nr][1];
col2 = listlist[1::nr][2];
col3 = listlist[1::nr][3];
translist = EvalList({col1, col2, col3});
リスト全体ではなく、「列」のサブセットのみを転置するだけで済む可能性があるため、私は後者の実装の方が好きです。
もちろん、これは For ループを使用して実行できますが、これを行う理由は、For ループが遅くなる可能性があるためです。 私は大きなテキストのブロックを扱っているのですが、これは作業を大幅にスピードアップするのに役立つと信じています。
クレジット: @vince_faller最初にこれを尋ねたので。for ループを使用しないリストのリストの転置
自動化とスクリプト作成Re: for ループを使用しないリストのリストの転置これについてもう少し考えてみます。私はまだ for ループを克服できませんが、誰かの役に立ちそうな場合に備えてこれを書き留めておこうと思いました。
// make a blank data table with the right shape
dt = As Table(J(nr, nc, .), <<PRIVATE></PRIVATE>
Re: for ループを使用しないリストのリストの転置@Craige_Halesクレイグさん、素晴らしい洞察力をありがとう。 私も同意します。for ループと並列割り当てメソッドの速度テストを行ったところ、並列割り当てメソッドの方がはるかに遅かったです。 私のリスト配列は 718r x 14182c だったので、要素数は 1,000 万を超えました。 スクリプトを約 10 分間実行しましたが、操作は完了しませんでした。 これは、上記のデータが予測するよりも少し遅いようですが、考慮するには変数が多すぎます (コンピューター システム、行と列の比率など)。 For ループは、同じテーブルに対して約 10.1 秒とはるかに高速です。
それでも思ったより遅いですが。 これを内部で実行できる JMP 関数があれば素晴らしいでしょう。
Re: for ループを使用しないリストのリストの転置しかし、いくつかのテストの後、単純なネストされたループは他の JSL ベースのアプローチよりも高速であると思います。
result = {};
for( c = 1, c <= nc, c += 1,
thisrow = {}; // build a row from a column
for( r = 1, r <= nr, r += 1,
thisrow[r] = testList[r][c];
);
result[c] = thisrow;
);@donmcormack - チャレンジ!
The blue-line for-loop is consistently better. The purple JSON-table might overtake it, but I'm running out of memory. The parallel-assign trick begins to fail for large numbers.青線の for ループの方が一貫して優れています。 紫色の JSON テーブルがそれを追い越す可能性がありますが、メモリが不足しています。 並列代入トリックは、数値が大きいと失敗し始めます。
並列割り当ては、おそらく常にスレッドを相互にブロックしています。 両者のオーバーヘッドが異なるため、最初は json データ テーブルよりも優れています。
Re: for ループを使用しないリストのリストの転置はい、リスト操作関数がもっとあればいいですね。 良い方法や速い方法は思いつきませんが、少し遊んだ後、これを思いつきました。 JMP 15 が必要ですが、14 では失敗します。
list = {{"lion", "tiger", "puma"}, {"lamp", "torch", "pharos"}, {"lark", "toucan", "pigeon"}, {"lawn", "terrace", "patio"}};
jlist = As JSON Expr( list );
dt1 = JSON To Data Table( jlist, invisible(1) );
dt1 << New Column( "row", numeric, setvalues( 1 + Floor( (0 :: (N Rows( dt1 ) - 1)) / N Items( list[1] ) ) ) );
dt2 = dt1 << Split( Split By( :row ), Split( column(dt1,1) ), Sort by Column Property, invisible(1) );
Close( dt1, nosave );
transposed = dt2[0, 0];
Close( dt2, nosave );
Show( list, transposed );リスト = {{"ライオン"、"トラ"、"ピューマ"}、{"ランプ"、"トーチ"、"ファロス"}、{"ヒバリ"、"オオハシ"、"ハト"}、{"芝生"、 "テラス"、"パティオ"}};
転置 = {{"ライオン"、"ランプ"、"ヒバリ"、"芝生"}、{"トラ"、"たいまつ"、"オオハシ"、"テラス"}、{"ピューマ"、"ファロス"、"ハト"、"パティオ"}};
中間テーブルを再表示して、何をしているのかを確認します。 実際のソリューションでは、長さが等しくない行を処理する必要があります。
Re: for ループを使用しないリストのリストの転置@Craige_Hales私が定期的に使用している素晴らしい説明を書いています。Parallel Assign を使用したマルチスレッドのトラブルシューティング
Re: for ループを使用しないリストのリストの転置@vince_faller
精神 == 吹き飛ばされました。
パラレル・アサイン機能について聞いたことはありません。 これを試してみましたが、はい、うまくいきました。 文字列を扱っていて、これは技術的には行列関数であるにもかかわらず、どういうわけか気にしません。 これを試して、for ループよりも速いかどうかを確認するのは興味深いでしょう。 分かり次第ここで更新しようと思います。
アイデアをありがとう!
Re: for ループを使用しないリストのリストの転置誰かが次のようなことをしているのを見たことがあります
{"cat", "dog", "mouse", "meow", "bark", "squeak"}[[1 1, 1 1]]
// and had it return
{{"cat", "cat"}, {"cat", "cat"}}
発見時の会話中に、私はそれを再現することができませんでした。それはすべて夢だったのでしょうか?
私の記憶が正しければ、彼らはどういうわけかこのように 1 行のフラットなリストから新しいリストを作成しました。たぶんちゃんと覚えていないんです。
そうは言っても、並列割り当てはおそらく非常に高速に実行できます
names default to here(1);
listlist = {{"cat", "dog", "mouse"}, {"meow", "bark", "squeak"}};
m = J(nc, nr, -1);
::trans_list = Aslist(m);
Parallel Assign({l = listlist},
m[a, b] = (
::trans_list[a][b] = l[b][a];
)
);
show(::trans_list);