转置列表列表 (summarize()),无需 for 循环任何人都可以想出一种方法来转置列表列表(如以下脚本中的内容),以便将每一行而不是按列分组在一起。
我知道我可以用 for 循环来做到这一点,但我想知道是否有更好或更简单的方法。
Names default to here(1);
dt = open("$SAMPLE_DATA\Big Class.jmp");
summarize(dt, d = By(:age, :sex));
rows = nitems(d);
cols = nitems(d[1]);
show(rows, cols);
// rows = 2;
// cols = 12;
为此,我想将其从 2 个 12 个列表更改为 12 个 2 个列表。
添加一些我认为可能喜欢这个挑战或已经拥有一些东西的人。
@pmroz , @Justin_Chilton , @gzmorgan0 , @msharp , @多发性硬化症
回复:在没有 for 循环的情况下转置列表列表(summarize())我有完全相同的问题@vince_faller 。 谢谢你的询问。 我已发布请求,要求将此类功能添加到下一版本的 JMP 中。 让我们来看看...
https://community.jmp.com/t5/JMP-Wish-List/Transpose-List-of-Lists-without-a-for-loop/idi-p/348968
回复:在没有 for 循环的情况下转置列表列表(summarize())重复:MS你的重复解决方案非常好。 
回复:在没有 for 循环的情况下转置列表列表(summarize())MS,重复一下,非常好!
回复:在没有 for 循环的情况下转置列表列表(summarize())Names default to here(1);
dt = open("$SAMPLE_DATA\Big Class.jmp");
//Since column formulas are by row, it uses a built in For Loop this maintains the table values but requires a table....<BR />//This is not a solution for two generic lists<BR />
dt << New Column( "Age,Sex",
Expression,
"None",
Formula( Eval List( {:age[Empty()], :sex[Empty()]} ) ),
Suppress Eval
);
myList= (Associative Array(Column("Age,Sex")) <<GET keys=""></GET>回复:在没有 for 循环的情况下转置列表列表(summarize())使用 JMP 14 中的新 Python 挂钩,我认为我可以作弊。它大部分有效。
Names Default To Here(1);
dt = Open("$SAMPLE_DATA\Big Class.jmp");
Summarize(dt, d = By(:age, :sex));
Python Init();
ml = Python Execute(
{d},
{x, d},
"\[
import numpy as np
x = np.transpose(d) # matrix product
print('x=', x)
]\"
);
Show( x, d );
Python Term();回复:在没有 for 循环的情况下转置列表列表(summarize())这是一个基于 Repeat() 的想法。 该函数本质上是一个循环,但直接返回列表,而不需要循环任何赋值。
在 JMP 的早期版本中,我发现在构建列表时 Repeat() 比 For() 快得多,但我认为这在 JMP 13 中已“修复”。
Names Default To Here(1);
dt = Open("$SAMPLE_DATA\Big Class.jmp");
Summarize(dt, d = By(:age, :sex));
transposed_d = Local({i = 0}, Repeat({i++ ; Eval List({d[1][i], d[2][i]})}, N Items(d[1])));
回复:在没有 for 循环的情况下转置列表列表(summarize())我找到了这种方法,但速度较慢。:(
Names default to here(1);
dt = open("$SAMPLE_DATA\Big Class.jmp")
summarize(dt, list = By(:age, :sex));
rows = nitems(list[1]);
cols = nitems(list);
list_flat = parse("{"||substitute(char(list), "}", "", "{", "")||"}");
insert into(list_flat, repeat({"@@@"}, rows));
list_sort = list_flat[ shape(1::rows*(cols+1), cols+1)` ];
remove from(list_sort, -1);
t_list = parse("{"||
substitute(char(list_sort),
", \!"@@@\!",", "},{"
)
||"}");
回复:在没有 for 循环的情况下转置列表列表(summarize())PMROZ 的嵌套 for 循环可能是最好的。如果您正在寻找替代方案,我可以想到另外两种方法。
如果您的数据都是数字,您可以使用非常光滑的矩阵。然而,这没有 for 循环,从汇总返回的列表列表返回所有字符值,即使对于数字列也是如此。这意味着您需要一个嵌套的 for 循环来将所有内容转换为数字(如果您的所有数据都是列),这样这对您的问题没有帮助。
第二个选项是将列表列表转换为数据表,转置它,然后返回。这需要两个 for 循环进行转换(我不知道有什么巧妙的方法可以在嵌套列表和数据表之间进行转换)。这可能比 PMROZ 的解决方案慢,因为您需要创建数据表的开销,但是,对于较大的数据集,它可能会更快。如果您实际上没有转换回列表列表,而只是使用转置的数据表,那么您也可以节省一些时间。
Names default to here(1);
dt = open("$SAMPLE_DATA\Big Class.jmp");
summarize(dt, d = By(:age, :sex));
rows = nitems(d);
cols = nitems(d[1]);
show(rows, cols);
//Turn List of Lists into DT ()
dtLL = New Table("Lists of Lists");
for(i=1,i<=nitems(d),i++,
dtLL << New Column(char(i), Character, Nominal, Values(d[i]));
);
//Transpose DT
cols = dtLL << Get Column Names;
dtT = dtLL << Transpose(columns(cols));
//Turn back into list of lists
trans_list = {};
for(i=2,i<=ncols(dtT),i++,
trans_list[i] = column(dtT,i) <<GET values=""></GET>回复:在没有 for 循环的情况下转置列表列表(summarize())卫生部!我想您可以将结果写入表中,转置该结果,然后从表中创建列表。 不过那里可能仍然有一个 for 循环。嗯嗯...
回复:在没有 for 循环的情况下转置列表列表(summarize())我觉得你没有阅读没有 for 循环的部分。 :p
回复:在没有 for 循环的情况下转置列表列表(summarize())这不是金表,但很实用。
Names default to here(1);
dt = open("$SAMPLE_DATA\Big Class.jmp");
summarize(dt, d = By(:age, :sex));
nrows = nitems(d);
ncols = nitems(d[1]);
show(nrows, ncols);
// nrows = 2;
// ncols = 12;
trans_list = {};
for (i = 1, i <= ncols, i++,
one_list = {};
for (k = 1, k <= nrows, k++,
one_list[k] = d[k][i];
);
trans_list[i] = one_list;
);
show(trans_list);
trans_list = {{"12", "F"}, {"12", "M"}, {"13", "F"}, {"13", "M"}, {"14", "F"}, {"14", "M"}, {"15", "F"}, {"15", "M"}, {"16", "F"}, {"16", "M"}, {"17", "F"}, {"17", "M"}};