如何使用 Mathematica 对 N 个列表按每个列表的元素总和进行排序?

发布于 2024-12-27 09:34:31 字数 147 浏览 0 评论 0原文

给定一个包含 k 个子列表的列表,让 A={{a1,a2,a3,...},{b1,b2,b3,...},...},我想按它们的 对这些子列表进行排序总计[A[i]]。有什么有效的方法可以做到这一点吗?

Given a list containing k sublists, let
A={{a1,a2,a3,...},{b1,b2,b3,...},...}, I want to sort those sublists by their Total[A[i]]. Is there any efficient way to make this?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(3

假扮的天使 2025-01-03 09:34:31

检查文档中的 SortBy 以了解对列表列表进行排序的一系列可能性。

 SortBy[A,Total]

给你所需要的。

编辑:根据下面向导先生的评论和其中链接中的解释,

SortBy[A,{Total}]

更好。

Check SortBy in documentation for a range of possibilities to sort lists of lists.

 SortBy[A,Total]

gives what you need.

EDIT: Per Mr. Wizard's comment below and the explanation in the link therein,

SortBy[A,{Total}]

is better.

笑,眼淚并存 2025-01-03 09:34:31

请注意,在许多情况下,基于 Ordering 的排序可能比 SortBy 更快,因为它允许我们利用矢量化。在这种特殊情况下,加速并不是那么巨大:

In[50]:= test = RandomInteger[10,{5000000,5}];

In[54]:= (res1=SortBy[test,{Total}]);//Timing
(res2 = test[[Ordering[Total[test,{2}]]]]);//Timing
res1===res2

Out[54]= {1.422,Null}
Out[55]= {1.125,Null}
Out[56]= True

但是,这是因为 Total 是一个内置函数。引入 SortBy 的全部原因是效率(即,对于单个比较函数。对于作为决胜局的多个比较函数,也方便)。它比 Sort 更高效,因为它更具体,因此绕过了主评估序列中的更多步骤。但是,SortBy 无法利用排序所基于的函数的可能的可列表性(向量化性质) - 它应用于逐一列表元素。带排序的解决方案确实明确利用了排序函数的整体销售计算的可能性(在本例中,Total[#,{2}]& 执行此操作),因此速度更快。

例如,如果任务是根据每个子列表中第二个、第三个和第四个元素的总数进行排序,我们会看到更大的性能差异:

In[60]:= (res3=SortBy[test,{Total[#[[2;;4]]]&}]);//Timing
(res4=test[[Ordering[Total[test[[All,2;;4]],{2}]]]]);//Timing
res3==res4

Out[60]= {2.39,Null}
Out[61]= {1.11,Null}
Out[62]= True

通常,性能提升对于排序函数来说是最大的,这些函数是两者都是计算密集型和矢量化的,因此当应用于整个列表时它们的速度要快得多。但请注意,对于大型列表,排序的性能提升永远不会像排序函数本身那样大。这是因为排序本身的复杂性,对于长度为 n 的大型列表,排序与 n*Log[n] 成正比,并且这种复杂性将始终存在。

Note that in many cases, sorting based on Ordering can be faster than SortBy, because it allows us to leverage vectorization. In this particular case, the speed-up is not that huge:

In[50]:= test = RandomInteger[10,{5000000,5}];

In[54]:= (res1=SortBy[test,{Total}]);//Timing
(res2 = test[[Ordering[Total[test,{2}]]]]);//Timing
res1===res2

Out[54]= {1.422,Null}
Out[55]= {1.125,Null}
Out[56]= True

But, this is because Total is a built-in function. The whole reason why SortBy was introduced, is efficiency (that is, for a single comparison function. For several comparison functions as tie-breakers, also convenience). It is more efficient that Sort, because it is more specific, and therefore by-passes more steps in the main evaluation sequence. However, there is no way for SortBy to leverage the possible listability (vectorized nature) of the function on which the sorting is based - it is applied to list elements one-by-one. The solution with ordering does explicitly leverage the possibility of whole-sale computation of the sorting function (in this case, Total[#,{2}]& does this), and therefore is faster.

If, for example, the task would be to sort according to a total of the second, third and fourth element in each sublist, we'd see a larger performance difference:

In[60]:= (res3=SortBy[test,{Total[#[[2;;4]]]&}]);//Timing
(res4=test[[Ordering[Total[test[[All,2;;4]],{2}]]]]);//Timing
res3==res4

Out[60]= {2.39,Null}
Out[61]= {1.11,Null}
Out[62]= True

Generally, the performance boost will be the largest for sorting functions which are both computationally intensive and vectorized, and such that they are much faster when applied to the whole list. Note, however, that the performance boost for sorting will never be as large as for the sorting function itself, for large lists. This is because of the intrinsic complexity of sorting, which is proportional to n*Log[n] for large lists of length n, and this complexity will always be there.

手心的海 2025-01-03 09:34:31

以下应该有效(但我现在无法测试):

Sort[A, Total[#1]<Total[#2]&]

The following should work (but I can't test it right now):

Sort[A, Total[#1]<Total[#2]&]
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文