我正在尝试编写一个函数,它将选择满足条件的表中的第一个元素。例如,如果我在第一列中给出了下表,并且在第二列中给出了感染疾病的人数,我想写一个参数,该参数将返回至少100个人被感染的时间。
0 1
1 2
2 4
3 8
4 15
5 29
6 50
7 88
8 130
9 157
10 180
11 191
12 196
13 199
14 200
所以从这张桌子上,我希望arguemnt告诉我,在8秒钟内,至少有100人被感染。我尝试使用SELECT来执行此操作,但我不确定如何将SELECT与2列表一起使用,并根据第二列中的条件在第一列中返回值。
答案 0 :(得分:3)
使用替换规则的替代方案是
ImportString["0 1 1 2 2 4 3 8 4 15 5 29 6 50 7 88 8 130 9 157 10 180 11 191 12 196 13 199 14 200", "Table"];
Partition[Flatten[%], 2]
% /. {___, x : {_, _?(# >= 100 &)}, ___} :> x
Mathematica搜索模式的算法确保这将返回第一个这样的情况。如果您想要所有案例,那么您可以使用ReplaceList。 我建议您阅读Patterns和Rules上的教程。
修改:ImportString
也适用于新格式化的数据 - 但您不再需要使用Partition
。
答案 1 :(得分:3)
您也可以使用简单的NestWhile
data = {{0,1},{1,2},{2,4},{3,8},{4,15},{5,29},{6,50},{7,88},{8,130},{9,157},{10,180},
{11,191},{12,196},{13,199},{14,200}};
NestWhile[# + 1 &, 1, data[[#, 2]] < 100 &] - 1
答案 2 :(得分:2)
以下是一些不同的方法,假设我已正确解释您的数据......
In[3]:= data = {{0,1},{1,2},{2,4},{3,8},{4,15},{5,29},{6,50},{7,88},{8,130},{9,157},{10,180},{11,191},{12,196},{13,199},{14,200}};
In[8]:= Cases[data, {_, _?(#>=100&)}, 1, 1][[1, 1]]
Out[8]= 8
In[9]:= Select[data, #[[2]]>=100&, 1][[1, 1]]
Out[9]= 8
我建议你阅读Part []以更好地理解这一点。
答案 3 :(得分:1)
我相信有一种比已经给出的方式更快的方法,但首先,通过使用Cases
而不是/;
进行测试,Joshua的&
方法可以更快一些
这是我建议的解决方案(编辑:为了清晰起见添加空格,因为双括号不在此处格式化):
dat[[
Position[
dat[[All, 2]],
x_ /; x >= 100,
1, 1
][[1, 1]],
1
]]
以下是提供的各种方法的时间安排。请注意,/.
方法仅运行一次,而其他方法运行loops
次。因此,在第一次测试中,它比Position
方法慢100倍。此外,NestWhile
方法仅返回索引,而不是实际的第一列元素。
In[]:=
dat = {Range[5000], Sort@RandomInteger[1*^6, 5000]} // Transpose;
lim = 300000; loops = 100;
dat /. {___, {x_, _?(# >= lim &)}, ___} :> x; // Timing
Do[ Cases[dat, {_, _?(# >= lim &)}, 1, 1][[1, 1]] , {loops}] // Timing
Do[ Cases[dat, {_, y_ /; y >= lim}, 1, 1][[1, 1]] , {loops}] // Timing
Do[ Select[dat, #[[2]] >= lim &, 1][[1, 1]] , {loops}] // Timing
Do[ NestWhile[# + 1 &, 1, dat[[#, 2]] < lim &] , {loops}] // Timing
Do[ dat[[Position[dat[[All, 2]], x_ /; x >= lim, 1, 1][[1, 1]], 1]] , {loops}] // Timing
Out[]= {0.125, Null}
Out[]= {0.438, Null}
Out[]= {0.406, Null}
Out[]= {0.469, Null}
Out[]= {0.281, Null}
Out[]= {0.125, Null}
使用较长的表(我省略了慢速方法):
In[]:=
dat = {Range[35000], Sort@RandomInteger[1*^6, 35000]} // Transpose;
lim = 300000; loops = 25;
Do[ Cases[dat, {_, _?(# >= lim &)}, 1, 1][[1, 1]] , {loops}] // Timing
Do[ Cases[dat, {_, y_ /; y >= lim}, 1, 1][[1, 1]] , {loops}] // Timing
Do[ Select[dat, #[[2]] >= lim &, 1][[1, 1]] , {loops}] // Timing
Do[ NestWhile[# + 1 &, 1, dat[[#, 2]] < lim &] , {loops}] // Timing
Do[ dat[[Position[dat[[All, 2]], x_ /; x >= lim, 1, 1][[1, 1]], 1]] , {loops}] // Timing
Out[]= {0.734, Null}
Out[]= {0.641, Null}
Out[]= {0.734, Null}
Out[]= {0.5, Null}
Out[]= {0.266, Null}
最后,确认协议:
In[]:= SameQ[
Select[dat, #[[2]] >= lim &, 1][[1, 1]],
dat[[Position[dat[[All, 2]], x_ /; x >= lim, 1, 1][[1, 1]], 1]]
]
Out[]= True