Задача функции Mathematica "AppendTo" - PullRequest
4 голосов
/ 12 марта 2011

Я новичок в Mathematica, и у меня возникла серьезная неисправность при добавлении столбцов в таблицу данных.Я использую Mathematica 7 в Vista.Я потратил много времени на 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 в пересмотренной таблице данных работают нормально.

Может кто-нибудь сказать мне, что я делаю неправильно?Заранее спасибо!

Ответы [ 5 ]

6 голосов
/ 12 марта 2011

Попробуем уточнить, из чего состоит метод двойной транспонирования.Я не претендую на оригинальность подхода.Я сосредоточен на ясности изложения.

Давайте начнем с 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 ed lists3 и lists2, потому что вторая транспозиция, транспозиция mydata отменяет предыдущую транспозицию.lists3 - это просто транспонирование mydata.(и наоборот).]

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

Теперь нам нужно только Transpose результат, чтобы получить желаемую финальную таблицу из пяти списков, каждый из которых занимает свой собственный столбец:

Transpose@lists5 // TableForm

final table

Надеюсь, это поможет пролить свет на то, как добавить два столбца в таблицу.Я нахожу этот путь достаточно ясным.Вы можете найти другой способ прояснить ситуацию.

4 голосов
/ 12 марта 2011

Здесь нужно рассмотреть несколько вещей. Во-первых, следующий код не дает мне никаких ошибок, поэтому здесь может происходить что-то еще. Возможно, вам следует опубликовать полный блок кода, который выдает ошибку.

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 будет использовать память бессмысленно.

В-третьих, есть лучшие способы выполнить эту задачу.

См. Как добавить в столбец и Вставка в двумерный список

Я должен отказаться от своего окончательного утверждения, что есть лучшие способы. После изменения Table на Do и проведения нескольких быстрых тестов это, по-видимому, конкурентный метод для некоторых данных.

Я использую Mathematica 7, так что, похоже, проблема не в этом.

1 голос
/ 12 марта 2011

Ну, вот мои два цента, и я считаю, что это очень быстрая и ИМХО самая понятная конструкция.

Сначала несколько тестовых массивов:

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 раз быстрее!) Метод.

1 голос
/ 12 марта 2011

Как уже упоминалось до , есть лучшие альтернативы для добавления столбцов в список, например Гарет и Mr.Wizard , Похоже, я не могу воспроизвести проблему на ст. 7. Но я хочу сосредоточиться на самой ошибке и посмотреть, сможем ли мы исправить ее таким образом. Когда 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 элементов.

0 голосов
/ 12 марта 2011

Я пытался воспроизвести это, но не удалось. Я использую Mma 8 на Windows XP; не похоже, что разница должна иметь значение, но кто знает? Я сказал, последовательно,

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 + обычное назначение?

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...