Mathematica“AppendTo”功能问题

时间:2011-03-11 22:14:44

标签: wolfram-mathematica

我是Mathematica的新手,我在向数据表中添加列时出现严重故障。我在Vista中运行Mathematica 7。在问这里之前我花了很多时间做RFD。

我有一个包含三列五行的数据表(mydata)。我正在尝试向表中添加两个包含五个元素的列表(有效地将两列添加到数据表中)。

完美地

Table[AppendTo[mydata[[i]],myfirstlist[[i]]],{i,4}] 

打印出表格:mydata // TableForm显示添加的列。

然而,当我尝试添加我的第二个列表时

Table[AppendTo[mydata[[i]],mysecondlist[[i]]],{i,5}]

Mathematica崩溃(!)或者我得到了大量Part::partwPart::spec错误,说第5部分不存在。

然而,在所有错误消息(如果Mathematica没有崩溃)之后,再次打印出数据表:mydata // TableForm显示数据表,其中包含五列,就像我想要的那样。修改后的数据表上的所有TableForm格式选项都可以正常工作。

有谁能告诉我我做错了什么?提前谢谢!

5 个答案:

答案 0 :(得分:6)

让我们试着澄清双转置方法的组成部分。我没有声称这种方法的原创性。我的重点是阐述的清晰度。

让我们从5个列表开始。首先,我们将三个放在一个表中。然后我们将添加最后两个。

food = {"bagels", "lox", "cream cheese", "coffee", "blueberries"};
mammals = {"fisher cat", "weasel", "skunk", "raccon", "squirrel"};
painters = {"Picasso", "Rembrandt", "Klee", "Rousseau", "Warhol"};
countries = {"Brazil", "Portugal", "Azores", "Guinea Bissau", 
             "Cape Verde"};
sports = {"golf", "badminton", "football", "tennis", "rugby"};

前三个名单 - 食物,哺乳动物,画家 - 成为lists3的元素。它们只是列表,但TableForm在表格中将其显示为

(lists3 = {food, mammals, painters}) // TableForm

lists3

mydata将是lists3转置的名称。现在,这三个列表显示为。这就是换位的作用:切换列和行。

(mydata = Transpose@lists3) // TableForm

mydata

这就是问题实际开始的地方。我们如何添加两个额外的列(即国家和体育列表)?所以让我们使用其余两个列表。

(lists2 = {countries, sports}) // TableForm

lists2

所以我们可以加入Transpose[mydata]lists2 ....

(lists5 = Join[Transpose[mydata], lists2]) // TableForm

lists5

[或者,我们可能会Join编辑lists3lists2因为第二个转置,mydata的转置会撤消先前的转置。 lists3只是mydata的转置。 (反之亦然)。]

In[]:= lists3 === Transpose[mydata]
Out[]:= True

现在我们只需要Transpose结果来获得所需的五个列表的最终表,每个列表都占据自己的列:

Transpose@lists5 // TableForm

final table

我希望这有助于阐明如何向表中添加两列。我发现这种方式相当清楚。你可能会发现其他一些更清晰的方法。

答案 1 :(得分:4)

这里有几件事要介绍。首先,以下代码没有给我任何错误,所以这里可能还有其他的东西。也许您应该发布一个产生错误的完整代码块。

mydata = Array[Subscript[{##}] &, {5, 3}];
myfirstlist = Range[1, 5];
mysecondlist = Range[6, 10];

Table[AppendTo[mydata[[i]], myfirstlist[[i]]], {i, 4}];
mydata // TableForm

Table[AppendTo[mydata[[i]], mysecondlist[[i]]], {i, 5}];
mydata // TableForm

其次,在此处使用Table没有任何意义,因为您直接修改mydataTable将毫无意义地耗尽内存。

第三,有更好的方法来完成这项任务。

请参阅How to prepend a columnInserting into a 2d list

我必须撤回我的确切陈述,即有更好的方法。将Table更改为Do并运行一些快速测试后,这似乎是某些数据的竞争方法。

我正在使用Mathematica 7,所以这似乎不是问题。

答案 2 :(得分:1)

正如前面提到的before,有better alternatives将列添加到列表中,就像GarethMr.Wizard一样,我似乎无法重现问题但是,我想关注错误本身,看看我们是否可以通过这种方式纠正错误。当Mathematica生成消息Part::partw时,它会吐出部分违规列表,如

Range[1000][[1001]]
Part::partw: Part 1001 of  
    {1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,
    31,32,33,34,35,36,37,38,39,40,41,42,43,44,45,46,47,48,49,50,<<950>>} 
    does not exist.

所以,我问的问题是哪个列表给我的问题?我最好的猜测是mysecondlist,我会检查Length @ mysecondlist以确定它是否实际上是5个元素。

答案 3 :(得分:1)

嗯,这是我的两分钱,我相信这是一个非常快速和恕我直言最容易理解的结构。

首先,一些测试数组:

m = RandomInteger[100, {2000, 10000}];
l1 = RandomInteger[100, 2000];
l2 = RandomInteger[100, 2000];
{r, c} = Dimensions[m];

我稍微增加了测试阵列的大小,以提高后续定时测量的准确性。

该方法涉及调用Part([[...]]),AllSpan(;;)的权力。

基本上,我在添加两列后设置了一个新的工作矩阵,其中包含数据数组的未来维度,然后使用AllSpan添加原始矩阵,并添加其他列仅All。然后我将废料矩阵复制回原始矩阵,因为其他方法也返回修改后的数据矩阵。

n = ConstantArray[0, {r, c} + {0, 2}];
n[[All, 1 ;; c]] = m;
n[[All, c + 1]] = l1;
n[[All, c + 2]] = l2;
m = n;

至于时间:

Mean[
 Table[
  First[
   AbsoluteTiming[
    n2 = ConstantArray[0, {r, c} + {0, 2}];
    n2[[All, 1 ;; c]] = m;
    n2[[All, c + 1]] = l1;
    n2[[All, c + 2]] = l2;
    m2 = n2;
    ]
   ],
  {10}
  ]
 ]

0.1056061

(平均10次运行)

使用Do(Mr.Wizard和OP)建议的另一种方法:

Mean[
 Table[
  n1 = m;
  First[
   AbsoluteTiming[
    Do[AppendTo[n1[[i]], l1[[i]]], {i, 2000}]; 
    Do[AppendTo[n1[[i]], l2[[i]]], {i, 2000}];
    ]
   ],
  {10}
  ]
 ]

0.4898280

结果是一样的:

In[9]:= n2 == n1

Out[9]= True

因此,概念上简单快捷(快5倍!)的方法。

答案 4 :(得分:0)

我试图重现这个但失败了。我在Windows XP上运行Mma 8;看起来好像差别不大,但谁知道呢?我先后说过,

myData = {{1, 2, 3}, {2, 3, 4}, {8, 9, 10}, {1, 1, 1}, {2, 2, 2}}
myFirstList = {9, 9, 9, 9, 9}
mySecondList = {6, 6, 6, 6, 6}
Table[AppendTo[myData[[i]], myFirstList[[i]]], {i, 4}]
Table[AppendTo[myData[[i]], mySecondList[[i]]], {i, 5}]
myData // TableForm

并且得到(0)没有崩溃,(1)没有错误或警告,以及(2)我预期的输出。 (注意:我在第一组追加的限制中使用了4而不是5,就像在你的问题中一样,以防万一引起麻烦。)

Mma文档声称AppendTo[a,b]始终等同于a=Append[a,b],这表明它不会就地修改列表。但我想知道AppendTo是否有时 修改列表时认为这样做是安全的;那么如果它认为它是安全的而不是,则可能会产生令人讨厌的后果。如果用AppendTo +普通作业替换Append,是否仍会发生奇怪的错误消息和崩溃?