Wolfram mathematica 使用Total和threshold参数减少列表长度

Wolfram mathematica 使用Total和threshold参数减少列表长度,wolfram-mathematica,Wolfram Mathematica,我正在寻找一种方法,用Total函数和threshold参数来减少一个巨大列表的长度。我想避免使用For和If(来自旧习惯) 例如: 我要“减少”的列表:{1,5,3,8,11,3,4},阈值为5 我想要的输出:{6,11,11,7} 这意味着我在列表的第一部分使用Total函数,并查看该函数的结果是否高于阈值。如果是这样,我使用Total函数的结果并转到列表的下一部分 另一个例子是阈值为5的{1,1,1,1}。结果应该是{5} 谢谢 编辑:它正在工作,但速度相当慢。为了更快,有什么想法吗 编辑

我正在寻找一种方法,用Total函数和threshold参数来减少一个巨大列表的长度。我想避免使用For和If(来自旧习惯)

例如: 我要“减少”的列表:
{1,5,3,8,11,3,4}
,阈值为
5

我想要的输出:
{6,11,11,7}
这意味着我在列表的第一部分使用Total函数,并查看该函数的结果是否高于阈值。如果是这样,我使用Total函数的结果并转到列表的下一部分

另一个例子是阈值为
5
{1,1,1,1}
。结果应该是
{5}

谢谢

编辑:它正在工作,但速度相当慢。为了更快,有什么想法吗

编辑2:循环内容(退出简单而非智能)

Wizard先生的新fast:

   f6[lst_, thr_] := 
 Reap[Sow@Fold[If[Min@# > thr  , Sow@#1; #2, #1 + #2] &, 0, lst]][[2, 
   1]]
那要快40倍。非常感谢

Thread[{resP, resU}] == f6[Thread[{list1,list2}], 5] True

我将您的要求解释为:

  • 如果列表中的某个元素小于阈值,则将其添加到列表中的下一个元素中
  • 重复此过程,直到列表不再更改
因此,对于阈值
5
和输入列表
{1,5,3,8,11,3,4}
,您将得到

{6,3,8,11,3,4}
{6,11,11,3,4}
{6,11,11,7}
编辑

我现在已经测试了这个解决你问题的方法

使用替换规则执行操作:

myList = {1,5,3,8,11,3,4}
threshold = 5
mylist = mylist //. {a___, b_ /; b < threshold, c_, d___} :> {a, b+c, d}
myList={1,5,3,8,11,3,4}
阈值=5
mylist=mylist/。{a_uuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuu

注意
ReplaceRepeated
(符号化
/.
)的使用

我将您的要求解释为:

  • 如果列表中的某个元素小于阈值,则将其添加到列表中的下一个元素中
  • 重复此过程,直到列表不再更改
因此,对于阈值
5
和输入列表
{1,5,3,8,11,3,4}
,您将得到

{6,3,8,11,3,4}
{6,11,11,3,4}
{6,11,11,7}
编辑

我现在已经测试了这个解决你问题的方法

使用替换规则执行操作:

myList = {1,5,3,8,11,3,4}
threshold = 5
mylist = mylist //. {a___, b_ /; b < threshold, c_, d___} :> {a, b+c, d}
myList={1,5,3,8,11,3,4}
阈值=5
mylist=mylist/。{a_uuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuu

注意
ReplaceRepeated
(符号化
/.
)的使用

这是一种明显的方法,速度快了300倍。。漂亮并不总是最好的

t = Random[Integer, 10] & /@ Range[2000];
threshold = 4;
Timing[
  i = 0; 
  t0 = Reap[
     While[i < Length[t], s = 0; 
     While[++i <= Length[t] && (s += t[[i]]) < threshold ]; 
     Sow[s]]][[2, 1]]][[1]]
Total[t] == Total[t0]
Timing[ t1 = 
   t //. {a___, b_ /; b < threshold, c_, d___} -> {a, b + c, d} ][[1]]
t1 == t0
t=Random[Integer,10]&/@Range[2000];
阈值=4;
时机[
i=0;
t0=收获[
而[i<长度[t],s=0;
而[++i{a,b+c,d}][[1]]
t1==t0

这里有一个明显的方法,速度快了300倍。漂亮并不总是最好的

t = Random[Integer, 10] & /@ Range[2000];
threshold = 4;
Timing[
  i = 0; 
  t0 = Reap[
     While[i < Length[t], s = 0; 
     While[++i <= Length[t] && (s += t[[i]]) < threshold ]; 
     Sow[s]]][[2, 1]]][[1]]
Total[t] == Total[t0]
Timing[ t1 = 
   t //. {a___, b_ /; b < threshold, c_, d___} -> {a, b + c, d} ][[1]]
t1 == t0
t=Random[Integer,10]&/@Range[2000];
阈值=4;
时机[
i=0;
t0=收获[
而[i<长度[t],s=0;
而[++i{a,b+c,d}][[1]]
t1==t0

我建议对此类操作使用
折叠
,结合链表或
Sow
收获
来累积结果。
追加
很慢,因为Mathematica中的列表是数组,每次追加元素时都必须重新分配

首先是:

lst = {2, 6, 4, 4, 1, 3, 1, 2, 4, 1, 2, 4, 0, 7, 4};
以下是链接列表版本:

Flatten @ Fold[If[Last@# > 5, {#, #2}, {First@#, Last@# + #2}] &, {{}, 0}, lst]
这就是展平之前的输出:


以下是使用
播种
收获
的方法:

Reap[Sow @ Fold[If[# > 5, Sow@#; #2, # + #2] &, 0, lst]][[2, 1]]
适用于其他问题的类似方法:

Fold
外部的
Sow@
有效地追加了序列的最后一个元素,否则该元素将被算法删除


以下是打包为函数的方法,以及便于比较的george方法:

f1[lst_, thr_] := 
  Flatten @ Fold[If[Last@# > thr, {#, #2}, {First@#, Last@# + #2}] &, {{}, 0}, lst]

f2[lst_, thr_] := 
  Reap[Sow@Fold[If[# > thr, Sow@#; #2, # + #2] &, 0, lst]][[2, 1]]

george[t_, thresh_] := Module[{i = 0, s},
  Reap[While[i < Length[t], s = 0; 
     While[++i <= Length[t] && (s += t[[i]]) < thresh]; Sow[s]]][[2, 1]]
  ]
1.279

0.593

0.468


对于这种操作,我建议使用
Fold
,结合链表或
Sow
eaw
来累积结果。
Append
很慢,因为Mathematica中的列表是数组,每次追加元素时都必须重新分配

首先是:

lst = {2, 6, 4, 4, 1, 3, 1, 2, 4, 1, 2, 4, 0, 7, 4};
以下是链接列表版本:

Flatten @ Fold[If[Last@# > 5, {#, #2}, {First@#, Last@# + #2}] &, {{}, 0}, lst]
这就是展平之前的输出:


以下是使用
播种
收获
的方法:

Reap[Sow @ Fold[If[# > 5, Sow@#; #2, # + #2] &, 0, lst]][[2, 1]]
适用于其他问题的类似方法:

Fold
外部的
Sow@
有效地追加了序列的最后一个元素,否则该元素将被算法删除


以下是打包为函数的方法,以及便于比较的george方法:

f1[lst_, thr_] := 
  Flatten @ Fold[If[Last@# > thr, {#, #2}, {First@#, Last@# + #2}] &, {{}, 0}, lst]

f2[lst_, thr_] := 
  Reap[Sow@Fold[If[# > thr, Sow@#; #2, # + #2] &, 0, lst]][[2, 1]]

george[t_, thresh_] := Module[{i = 0, s},
  Reap[While[i < Length[t], s = 0; 
     While[++i <= Length[t] && (s += t[[i]]) < thresh]; Sow[s]]][[2, 1]]
  ]
1.279

0.593

0.468


哦,非常感谢!我明天会测试并告诉你结果。我必须处理约50万个值的列表(主要由0或1组成):希望这不会永远发生。如果您的数据序列大多是0和1,为什么不在问题中包含这些信息,可能会有一种更快的方法来处理这些序列。因为值的分布是“随机的”:这意味着我将有大部分0和1,但也有2、3甚至4等等。我不知道这是一个重要的信息,对此表示抱歉。我正在工作,但速度很慢。为了更快,有什么建议吗?是的,当然。目前,我正在使用For循环和If语句。哦,非常感谢!我明天会测试并告诉你结果。我将有要处理约50万个值(主要由0或1组成)的列表:希望不会花费很长时间。好吧,如果您的数据系列主要是0和1,为什么不在问题中包含这些信息,可能有一种更快的方法来处理这些系列。因为值的分布是“随机的”:这意味着我将有大部分的0和1,但也有2、3甚至4等等。我不知道这是一个重要的信息,对此表示抱歉。我正在工作,但速度很慢。为了更快,有什么建议吗?是的,当然。目前,我正在使用For循环和If语句。谢谢