Условное объединение данных в Mathematica

#data-structures #merge #wolfram-mathematica #conditional

#структуры данных #слияние #wolfram-mathematica #условные операторы

Вопрос:

Мне нужно объединить данные из 2 разных источников. Приведенные ниже таблицы иллюстрируют, что у меня есть :

введите описание изображения здесь

И желаемый результат :

введите описание изображения здесь

Идея заключается:

  • Загляните в первую колонку. Таблицы 1 (пробно)

  • Ищите это в первой колонке. Таблицы 2.

  • Убедитесь, что значения во втором столбце. равны (на самом деле эти col. не будут расположены в одних и тех же местах в двух списках)

  • Если проверка пройдена, добавьте значения, расположенные в колонках 3 и 4 (Cond1 и Cond2), к строке в Table2.

  • Я не думаю, что сохраню заголовки в реальной структуре, поэтому это не должно представлять дополнительной проблемы, но предложения по работе с заголовками приветствуются (удалить ли их и сохранить где-нибудь в другом месте или обработать особым образом)

**

РЕДАКТИРОВАТЬ: Придание точности форме моих данных и моим целям

**

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

Я записываю движения глаз (саккады и фиксации) и ответы испытуемых на задание во время отображения стимулов на экране.

  • Каждая пробная версия состоит из двух последовательных отображений по 3 секунды каждое. Это 2AFC (принудительный выбор с двумя альтернативами).
  • Каждый дисплей состоит из представления рамки (размером примерно 1/4 экрана) с 8 фигурами в ней, отображаемыми в 1 из 4 квадрантов экрана.
  • Существует 5 условий того, из чего состоит сам фрейм, и, таким образом, для каждого испытания возможны 10 условий (1 условие фрейма против другого без повторения).
  • Существует 2 показателя: выбор объекта и движения глаз, записанные при просмотре стимулов.

Я получаю эти данные из 2 разных источников :


  • Машина «отображения», которая обеспечивает

-Пробный номер / отображаемый номер

-Информация об экране

-Условия

-Ответ на тему

— Координаты X и Y, а также размер 11 объектов, составляющих отображаемые стимулы.

В этой матрице каждая строка является отображением, поэтому столбец DisplayNO будет иметь значение от 1 до 400 (1,2,3,4, …, 400), в то время как столбцы TrialNO фактически имеют значение от 1 до 200 (1,1,2,2,..,200,200) поскольку на пробную версию приходится 2 показа.


  • Машина «отслеживания глаз», которая обеспечивает :

-Некоторая похожая информация (отображаемое число (от 1 до 400), которое будет использоваться для объединения 2, номер условия, который можно использовать для проверки ставки сопоставления. 2)

Затем огромное количество переменных, описывающих движения глаз :

-Длительность фиксаций и саккад, местоположения, синхронизация и т.д. (около 100 столбцов)

В этой матрице каждая строка является фиксацией.Затем характеристики саккады приводятся в столбцах (предыдущая и следующая саккады) И для каждого отображения может быть от 1 до 30-50 исправлений. В результате у меня могло бы быть 19 строк данных для первого отображения и 5 для второго.


  • Первым шагом является объединение структуры данных 2 на 2 для получения большой структуры, каждая строка которой соответствует фиксации.

  • Придется сделать это для каждого объекта, затем объединить данные объектов друг над другом.

Это мой план разобраться с этим монстром позже (и это объяснит мои потребности в других вопросах) :

  • Извлеките заголовок и номера столбцов.

  • Представьте их по группам в удобной табличной форме -Общая информация (идентификатор пробной версии, условие, идентификатор субъекта …), -Информация о отображении (координаты объектов на экране), -Информация об исправлениях и т.д…

  • Для каждой из этих переменных имеется краткое описание типа данных (строка, число, текст), диапазона, количества различных значений, которые принимают столбцы, и некоторой базовой описательной статистики.

  • Система для извлечения частей этого набора условно (например: извлечение номера условия, длительности фиксаций для выбранного отображения конкретным объектом) Таким образом, я извлекаю некоторую четко определенную таблицу, с которой затем выполняю свой анализ, не касаясь исходных данных.

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

Комментарии:

1. Чего вы ожидаете, когда проверка не проходит? Следует ли создавать неровный массив (строки разной длины) или следует использовать такую заливку, как Null ?

2. Кроме того, для оптимизации было бы полезно узнать больше о «форме» ваших данных. TrialNO Всегда ли это в порядке вещей? Сколько может быть различных TrialNO типов? Могут ли все элементы таблицы быть выражены в действительных числах машинного размера (что могло бы сделать все быстрее)? Сколько строк и столбцов, вероятно, будут содержать ваши данные?

3. @Mr.Wizard : Заполнение, такое как Null, было бы идеальным. Я не смог бы использовать данные, если бы проверка не прошла. Я не уверен, что полностью воплощает «реальные значения машинного размера», но TrialNO, скорее всего, будет целыми числами от 1 до 400. Я думаю, мне нужно рассказать больше о том, что я пытаюсь сделать, поскольку все мои вопросы, за исключением раскраски переменных, относятся к частям программы, которую я пытаюсь написать для обработки моих данных. Я скоро отредактирую этот вопрос, пытаясь предоставить как можно больше точной информации как о том, что у меня есть, так и о том, что мне нужно, чтобы иметь возможность с этим делать. Спасибо Dr. !

4. 500, поскольку на этот вопрос уже есть ответы, если вы собираетесь опубликовать длинную спецификацию программы, возможно, будет лучше сделать это в новом вопросе. С другой стороны, несколько разъяснений к этому вопросу могли бы помочь в уточнении уже данных ответов. Причина, по которой я спросил о «реальных значениях размера компьютера», заключается в том, что если все записи в прямоугольном массиве являются стандартными числами с плавающей запятой (или целыми числами), то Mathematica может использовать «упакованные массивы», которые обычно занимают меньше памяти и работают быстрее, если код разработан с учетом этого.

5. 500, спасибо за всю информацию. Я слишком устал, чтобы заниматься этим сейчас, но я поработаю над этим позже. Я ожидаю, что вы можете получить некоторые обновленные ответы за это время.

Ответ №1:

Здесь есть возможность:

 MergeTables[data1_, data2_, samepos1_, samepos2_] :=
 Cases[data1, 
  x_ :> Block[{y = 
      Cases[data2, z_ /; z[[samepos2]] === x[[samepos1]]]},
    Apply[Sequence, Join[x, Delete[#, Thread[{samepos2}]]] amp; /@ y]]]
  

Использование:

 MergeTables[data2, data1, {1, 2}, {1, 2}]
  

Комментарии:

1. Спасибо, Саша! Я пока оставлю это без ответа, чтобы увидеть предложенную альтернативу, но это работает очень хорошо!

Ответ №2:

Я жду более подробного описания ваших данных для лучшей оптимизации.

 checkMerge[src_, trg_, si_, ti_, sp_] :=
 Module[{rls, ext},
  rls = #[[si]] -> #[[sp]] amp; /@ src;
  AppendTo[rls, _ -> {,}];
  ext = Replace[trg[[All, ti]], Dispatch@rls, 1];
  ArrayFlatten[{{trg, ext}}]
 ]
  

Синтаксис такой:

  • src = список «источников» (data1)
  • trg = «целевой» список (data2)
  • si = список индексов из источника для сравнения
  • ti = список индексов из целевого объекта для сравнения
  • sp = список индексов из источника для добавления к целевому

Для вашего примера это было бы:

 checkMerge[data1, data2, {1,2}, {1,2}, {3,4}]
  

Я должен был угадать уровень изменений, которые необходимо учесть из:

(на самом деле эти col. не будут расположены в одних и тех же местах в двух списках)

Следовательно, в этом может быть слишком много или слишком мало специфичности.

  1. В настоящее время sp должен быть список из двух индексов (номеров столбцов) только потому, что это немного упростило задачу, и я не уверен, чего вы хотите. Вы хотите указать, какие элементы берутся из data1 и добавляются к data2 , или это должны быть все элементы после сравниваемых, или что-то еще?

  2. Если для si , ti , sp имеются стандартные значения, можно добавить значения по умолчанию, чтобы вы могли их опустить, если только не требуются другие значения.

  3. Я предположил, что можно расширить строки, которые не совпадают с Null , чтобы создать прямоугольный массив; впоследствии их можно удалить, чтобы получить неровный массив, если таково ваше желание.

Комментарии:

1. Я только что понял, что много раз называл вас Dr. Извините за это. У меня возникла проблема с применением вашего кода к моим данным. Столбцы, которые необходимо учитывать в «исходных» данных (тот, из которого мы копируем столбцы), являются № 1 и 2, которые должны быть соответственно сопоставлены с № 13 и 8 в «Целевых» данных (тот, который станет унифицированным набором). Также я хотел бы скопировать все столбцы, кроме рассмотренных 2, и не знал бы, как это настроить.

2. Я все же тестировал, как если бы я пытался просто добавить 3 и 4, и вот что я сделал: checkMerge[matlabDataLAEH10, eyelinkDataLAEH10, {1,2}, {13,8}, {3,4}]; Однако столбцы добавляются, но заполняются значением Null. Может ли быть так, что мои списки все еще имеют свои заголовки? Заранее большое спасибо за вашу помощь.

3. @500, когда меня называли «Dr.», хотя и очень неточно, было забавно. 🙂 Мое прозвище — дань уважения ведущему научного телевидения, который оказал влияние на меня в детстве. Что касается проблемы, не могли бы вы загрузить образец данных на свой сервер в формате Mathematica .m? Мне будет намного проще отслеживать проблемы таким образом. Как только у меня это заработает, я обновлю свой ответ, чтобы он также соответствовал вашей спецификации данных для добавления. Кроме того, я все равно вернусь к более масштабной спецификации задачи, когда смогу уделить ей больше времени.

4. Теперь это работает! Это была моя ошибка, что я не выбрал правильные столбцы. Не могли бы вы подумать о том, как добавить заголовок columns, поскольку они не проходят тест? Они все еще отображаются как null. Но, действительно, спасибо, это тоже кажется быстрым методом!

Ответ №3:

Ответ Саши слишком классный, я даже пока не знаю, как это работает.

Вот моя попытка, и, будучи скорее структурным, чем функциональным программистом, я использовал для этого таблицу[] (БОЖЕ мой!). Ну, таблица [] все еще находится на грани функционального программирования 🙂

(Здесь A — data2, а B — data1)

 n=Length[A];  m=Length[B];

isMatch[a_,b_] := a[[1]]=== b[[1]]amp;amp;a[[2]]===b[[2]]

A[[1]] = A[[1]]~Join~B[[1,3;;-1]]; (*do the header on its own*)

Table[If[ isMatch[B[[i]],A[[j]]], 
          A[[j]] = Join[A[[j]],B[[i,3;;-1]]] 
     ],

     {i,2,m},{j,2,n}        
];

A//TableForm
  

—Nasser

Комментарии:

1. Спасибо, Насер! Определенно чувствуется опыт Matlab там! Я уверен, что с таким кодом, который предоставляет Саша, и благодаря замечательной помощи Mathematica мы скоро станем отличными функциональными программистами!