Избегайте репликации целых таблиц в Matlab `join`'s - PullRequest
0 голосов
/ 03 мая 2018

У меня есть таблица T записей и полей. Я хочу создать новое поле и заполнить его результатом поиска другой таблицы L. Это означает, что я буду использовать одно или несколько полей в T в качестве внешнего ключа. В SQL я могу ОБНОВИТЬ вновь созданное поле в таблице T, используя JOIN с таблицей L. И наоборот, Matlab не обновляет существующую таблицу при выполнении join; это создает совершенно новую таблицу, которая затем используется для замены исходной таблицы T. Кажется, что для заполнения одного поля требуется много репликации данных. Это избегается под капотом? Есть ли шаблон дизайна кода или идиома, который избегает этого, но все еще достаточно читабелен и не слишком компрометирует компактность кода?

Хотя я задавал этот вопрос в контексте join, меня в целом интересовали стратегии, позволяющие избежать репликации таблиц во всех вариациях объединений Matlab.

Я опишу пример того, как для каждой записи в Table1, ForeignKey используется для поиска Data в Table2.

        Table1
-----------------------------
SomeField NewField ForeignKey
--------- -------- ----------
someData1 dummy    a
someData2 dummy    b
someData3 dummy    a
someData4 dummy    b
someData5 dummy    a

Table2
--------
Key Data
--- ----
a   apple
b   banana

Следующий код SQL выполняет поиск. Запись в поле Data затем объединяется с содержимым поля SomeField в Table1 и сохраняется в поле NewField.

UPDATE Table1 INNER JOIN Table2
ON Table1.ForeignKey = Table2.Key
SET Table1.NewField = Table1.SomeField & Table2.Data

Обновленный Table1:

        Table1
------------------------------------
SomeField NewField        ForeignKey
--------- --------------- ----------
someData1 someData1apple  a
someData2 someData2banana b
someData3 someData3apple  a
someData4 someData4banana b
someData5 someData5apple  a

Интересно отметить, что Table INNER JOIN Table2 на самом деле не создан. Он только «виртуально» создан для включения расчета, с помощью которого обновляется Table1. В отличие от этого, Matlab JOIN создает фактическую объединенную таблицу, и для выполнения расчетов требуется отдельная операция.

Ответы [ 2 ]

0 голосов
/ 05 мая 2018

Операция, которую вы выполняете, должна выглядеть примерно так:

table1 = table({'someData1';'someData2';'someData3';'someData4';'someData5'},...
   {'a';'b';'a';'b';'a'},'VariableNames',{'SomeField','ForeignKey'});
table2 = table({'a';'b'},{'apple';'banana'},'VariableNames',{'Key','Data'});

table3 = join(table1,table2,'LeftKeys','ForeignKey','RightKeys','Key')

Это приводит к следующей таблице:

 SomeField     ForeignKey      Data  
___________    __________    ________

'someData1'    'a'           'apple' 
'someData2'    'b'           'banana'
'someData3'    'a'           'apple' 
'someData4'    'b'           'banana'
'someData5'    'a'           'apple' 

А затем вы применяете какую-то операцию к столбцам SomeField и Data.

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

Если вы все еще беспокоитесь о копировании больших объемов данных (как я уже говорил, это не так из-за отложенного копирования), вы можете получить столбец Data выше, используя следующие операции на основе набора:

[~,index] = ismember(table1.ForeignKey,table2.Key);
data = table2.Data(index);

Здесь data - это массив ячеек, идентичный table3.Data. В любом случае, созданные здесь значения index - это то, что SQL создаст внутри для этой операции JOIN. Если table1.ForeignKey отсутствует в table2.Key, соответствующее значение index равно 0 (индексы MATLAB начинаются с 1). В этом случае вы не можете использовать index непосредственно для индексации, вам нужно будет использовать дополнительный уровень индексации, чтобы получить только допустимые строки:

[valid,index] = ismember(table1.ForeignKey,table2.Key);
data1 = table1.SomeField(valid)
data2 = table2.Data(index(valid));

Обратите внимание, что table/join использует ismember точно таким же образом, затем копирует левую таблицу (что приводит к тому, что копия ссылается на данные во входной таблице из-за ленивого копирования) и добавляет столбцы для нее справа таблица.

0 голосов
/ 03 мая 2018

Я не специалист по таблицам, но я могу дать представление о том, как MATLAB работает с данными такого типа.

Объект MATLAB table содержит матрицу для каждого столбца.

Копирование матрицы в MATLAB не копирует данные. MATLAB использует ленивое копирование. Это означает, что копия ссылается на те же данные, что и оригинал (до тех пор, пока копия или оригинал не будут изменены, после чего копия будет сделана). Это поведение хорошо документировано (1) , (2) .

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

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

Однако, если операция join вызывает замену или удаление строк, все это спорный вопрос. Данные будут скопированы.

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