从mathematica表中选择数据

发布于 2024-10-02 06:00:56 字数 345 浏览 3 评论 0原文

我正在尝试编写一个函数,该函数将选择表中满足条件的第一个元素。例如,如果给我下表,第一列是时间,第二列是感染某种疾病的人数,我想编写一个参数来返回至少 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

因此,从这张表中,我希望论证告诉我,在 8 秒内,至少有 100 人被感染。我尝试使用 SELECT 来执行此操作,但我不确定如何将 SELECT 与 2 列的表一起使用,并让它根据第二列中的条件返回第一列中的值。

I'm trying to write a function that will take select the first element in the table that satisfies a criteria. For example, if I am given the following table with times in the first column and number of people infected with a disease in the second, I want to write an argument that will return the time where at least 100 people are infected.

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

So from this table, I want the arguemnt to tell me that at 8 seconds, at least 100 people were infected. I tried using SELECT to do this, but I'm not sure how to use SELECT with a table of 2 columns and have it return a value in the first column based on criteria from the second column.

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

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

发布评论

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

评论(4

↘紸啶 2024-10-09 06:00:56

使用替换规则的另一种方法是

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。
我建议您阅读有关 模式规则


编辑:ImportString 也适用于新格式化的数据 - 但您不再需要使用 Partition

An alternative that uses replacement rules is

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

The algorithm with which Mathematica searches for patterns ensures that this will return the first such case. If you want all cases then you can use ReplaceList.
I suggest you read the tutorial on Patterns and Rules.


Edit: ImportString works on the newly formatted data as well - but you no longer need to use Partition.

一紙繁鸢 2024-10-09 06:00:56

您还可以使用简单的 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

You can also use a simple 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
你又不是我 2024-10-09 06:00:56

这里有几种不同的方法来做到这一点,假设我已经正确解释了您的数据......

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

我建议您阅读第 [] 部分以更好地理解这一点。

Here are a few different ways to do this, assuming I've interpreted your data correctly...

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

I suggest you read up on Part[] to understand this better.

天赋异禀 2024-10-09 06:00:56

我相信有一种比已经给出的方法更快的方法,但首先,使用 /; 而不是 & 可以使 Joshua 的 Cases 方法更快一点; 用于测试。

这是我建议的解决方案(编辑:为了清楚起见,添加空格,因为双括号不在这里格式化):

dat[[
  Position[
    dat[[All, 2]],
    x_ /; x >= 100,
    1, 1
  ][[1, 1]],
  1
]]

以下是所提供的各种方法的计时。请注意,/. 方法仅运行一次,而其他方法则运行循环 次。因此,在第一个测试中,它比 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

I believe there is a faster way than what has already been given, but first, Joshua's Cases method can be made a little faster by using /; rather than & for the test.

This is the solution I propose (edit: adding white space for clarity, since the double brackets do not format here):

dat[[
  Position[
    dat[[All, 2]],
    x_ /; x >= 100,
    1, 1
  ][[1, 1]],
  1
]]

Here are timings for the various methods offered. Please note that the /. method is only being run once, while the others are being run loops times. Therefore, in this first test it is 100x slower than the Position method. Also, the NestWhile method is only returning an index, rather than an actual first column element.

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}

With a longer table (I leave out the slow method):

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}

Finally, confirmation of agreement:

In[]:= SameQ[
         Select[dat, #[[2]] >= lim &, 1][[1, 1]],
         dat[[Position[dat[[All, 2]], x_ /; x >= lim, 1, 1][[1, 1]], 1]]
       ]

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