对于或同时循环在Mathematica代码总是让我感到有点脏,但我是困惑自己,试图做一些清单咀嚼所有的功能,并诉诸如下:
(* # Given a list of {x,y} pairs, transform the data as follows: every time
# there's a decrease in y-value from one datapoint to the next, say {x1,Y}
# followed by {x2,y}, add Y to the value of every datapoint on or after x2. *)
monotonify[data_] := Module[{data0, i, offset = 0},
data0 = data;
For[i = 2, i <= Length[data], i++,
If[data[[i-1,2]] > data[[i,2]], offset += data[[i-1,2]]];
data0[[i]] += {0,offset}];
data0](把y-值看作是里程计读数,有时会不小心重新设定-很明显是因为这个值减少了,而这是校验仪不应该做的。因此,我们通过在每次重置之前将最后一个已知值添加到所有未来值来转换读数。
你如何用一种很好的功能风格来写单调呢?
(事实上,我并不认为上述For循环非常好,这可能是一种温和的强迫症。)
发布于 2010-07-22 09:14:32
好的,现在我已经按照最初的要求修正了处理输入的方法。
从一个示例数据集开始:
dataset = {{a, 1}, {b, 2}, {c, 3}, {d, 4}, {e, 5}, {f, 0}, {g, 4},
{h,5}, {i, 6}, {j, 7}, {k, 4}, {l, 7}, {m, 8}, {n, 9}, {o, 0}, {p,2},
{q, 3}};采取转置:
trDataset = Transpose[dataset];接下来,只对Y值进行操作的函数:
trDataset[[2]] = FoldList[Plus, dataset[[1, 2]], Map[Max[#, 0] &, Differences[dataset[[All, 2]]]]]撤销换位:
dataset = Transpose[trDataset]现在的输出
{{a, 1}, {b, 2}, {c, 3}, {d, 4}, {e, 5}, {f, 5}, {g, 9}, {h, 10}, {i,
11}, {j, 12}, {k, 12}, {l, 15}, {m, 16}, {n, 17}, {o, 17}, {p,
19}, {q, 20}}我还没有测试过这个解决方案的性能。
编辑: OK,这是修复的基础,剩下的工作交给您@。这个单调性的版本只适用于一个数字列表,我还没有将它集成到我先前的建议中,即使用您的输入。
monotonify[series_] :=
Split[series, Less] //. {a___, x_List, y_List, z___} /;
Last[x] > First[y] -> {a, x, y + Last[x], z} // Flatten编辑2:另一个函数,它工作在一个数字列表上。这比我之前的尝试要快得多。
monotonify[series_] :=
Accumulate[Flatten[Map[Flatten[{#[[1]], Differences[#]}] &,
Split[series, Less]]]]发布于 2010-07-24 19:17:55
以下是另一个解决方案:
Module[{corr, lasts},
lasts = data[[All, 2]];
corr = Prepend[Accumulate[MapThread[If[#1 > #2, #1, 0] &, {Most[lasts], Rest[lasts]}]], 0];
Transpose[{data[[All, 1]], lasts + corr}]]它计算一个校正向量,然后将其添加到给定数据点的y值中。
发布于 2010-07-22 02:07:43
一旦关闭了gauntlet,我就无法尝试它,但我认为For循环版本更简单:
mon00[{prev_,offset_}, next_] := {next, offset + If[prev > next, prev, 0]}
monotonify0[list_] := list + Rest[FoldList[mon00, {-Infinity,0}, list]][[All,2]]
monotonify[data_] := Transpose@{#1, monotonify0[#2]}& @@ Transpose@data其思想是编写一个助手函数,它只对y-值的简单列表进行操作,然后使用双转置式成语对数据的第二列进行操作。
双转座式成语的方便参考
用于转换矩阵中的特定列,例如,用transformElementx替换4列矩阵第2列中的每个值x。
{#1, transformElement[#2], #3, #4}& @@@ matrix如果您需要转换一个包含整个列的函数的列,请使用以下成语:
Transpose @ {#1, transformList[#2], #3, #4}& @@ Tranpose@matrixhttps://stackoverflow.com/questions/3305138
复制相似问题