我是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::partw
和Part::spec
错误,说第5部分不存在。
然而,在所有错误消息(如果Mathematica没有崩溃)之后,再次打印出数据表:mydata // TableForm
显示数据表,其中包含五列,就像我想要的那样。修改后的数据表上的所有TableForm
格式选项都可以正常工作。
有谁能告诉我我做错了什么?提前谢谢!
答案 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
mydata
将是lists3
转置的名称。现在,这三个列表显示为列。这就是换位的作用:切换列和行。
(mydata = Transpose@lists3) // TableForm
这就是问题实际开始的地方。我们如何添加两个额外的列(即国家和体育列表)?所以让我们使用其余两个列表。
(lists2 = {countries, sports}) // TableForm
所以我们可以加入Transpose[mydata]
和lists2
....
(lists5 = Join[Transpose[mydata], lists2]) // TableForm
[或者,我们可能会Join
编辑lists3
和lists2
因为第二个转置,mydata
的转置会撤消先前的转置。
lists3
只是mydata
的转置。 (反之亦然)。]
In[]:= lists3 === Transpose[mydata]
Out[]:= True
现在我们只需要Transpose
结果来获得所需的五个列表的最终表,每个列表都占据自己的列:
Transpose@lists5 // TableForm
我希望这有助于阐明如何向表中添加两列。我发现这种方式相当清楚。你可能会发现其他一些更清晰的方法。
答案 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
没有任何意义,因为您直接修改mydata
。 Table
将毫无意义地耗尽内存。
第三,有更好的方法来完成这项任务。
请参阅How to prepend a column和Inserting into a 2d list
我必须撤回我的确切陈述,即有更好的方法。将Table
更改为Do
并运行一些快速测试后,这似乎是某些数据的竞争方法。
我正在使用Mathematica 7,所以这似乎不是问题。
答案 2 :(得分:1)
正如前面提到的before,有better alternatives将列添加到列表中,就像Gareth和Mr.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
([[...]]),All
和Span
(;;)的权力。
基本上,我在添加两列后设置了一个新的工作矩阵,其中包含数据数组的未来维度,然后使用All
和Span
添加原始矩阵,并添加其他列仅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
,是否仍会发生奇怪的错误消息和崩溃?