#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. не будут расположены в одних и тех же местах в двух списках)
Следовательно, в этом может быть слишком много или слишком мало специфичности.
-
В настоящее время
sp
должен быть список из двух индексов (номеров столбцов) только потому, что это немного упростило задачу, и я не уверен, чего вы хотите. Вы хотите указать, какие элементы берутся изdata1
и добавляются кdata2
, или это должны быть все элементы после сравниваемых, или что-то еще? -
Если для
si
,ti
,sp
имеются стандартные значения, можно добавить значения по умолчанию, чтобы вы могли их опустить, если только не требуются другие значения. -
Я предположил, что можно расширить строки, которые не совпадают с
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 мы скоро станем отличными функциональными программистами!