不使用 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 循環轉置列表列表
腳本回复:不使用 for 循環轉置列表列表再考慮一下這個。我仍然無法擊敗 for 循環,但我想我會把它寫下來以防它對任何人有幫助。
// make a blank data table with the right shape
dt = As Table(J(nr, nc, .), <<PRIVATE></PRIVATE>
回复:不使用 for 循環轉置列表列表@Craige_Hales感謝克雷格的深刻見解。 我同意,我對 for 循環與並行分配方法進行了速度測試,並行分配的速度要慢得多。 我的列表數組是 718r x 14182c,所以超過 1000 萬個元素。 我運行腳本約 10 分鐘,但操作沒有完成。 這似乎比您上面預測的數據慢一點,但要考慮的變量太多(例如計算機系統、列與行的比率?)。 對於同一張表,for 循環在 ~10.1s 時要快得多。
仍然比我想要的要慢。 如果有一個可以在內部執行此操作的 JMP 函數,那就太好了。
回复:不使用 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;
);@DonMcCormack - 挑戰!
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 數據表,因為兩者之間的開銷不同。
回复:不使用 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 );list = {{"lion", "tiger", "puma"}, {"lamp", "torch", "pharos"}, {"lark", "toucan", "pigeon"}, {"lawn", “露台”,“天井”}};
轉置= {{“獅子”,“燈”,“百靈”,“草坪”},{“老虎”,“火炬”,“巨嘴鳥”,“露台”},{“美洲獅”,“燈塔", "鴿子", "天井"}};
取消隱藏中間表以查看它在做什麼。 真正的解決方案應該處理長度不等的行。
回复:不使用 for 循環轉置列表列表@Craige_Hales寫了一個很好的解釋,我經常使用。使用 Parallel Assign 進行多線程故障排除
回复:不使用 for 循環轉置列表列表@vince_faller
頭腦==吹。
以前從未聽說過 Parallel Assign 功能。 我試過了,是的,它有效。 儘管我正在處理字符串並且這在技術上是一個矩陣函數,但它並不關心。 嘗試一下它會很有趣,看看它是否比 for 循環更快。 一旦我知道,將嘗試在這裡更新。
謝謝你的主意!
回复:不使用 for 循環轉置列表列表我發誓我看到有人做了類似的事情
{"cat", "dog", "mouse", "meow", "bark", "squeak"}[[1 1, 1 1]]
// and had it return
{{"cat", "cat"}, {"cat", "cat"}}
在 discovery 的一次演講中,但我一直無法重現它。難道一切都是夢?
如果我沒記錯的話,他們以某種方式從一個平面列表中形成了一個新列表,就像那樣。我可能記錯了。
話雖如此,您可能可以非常快地進行並行分配
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);