将 table 的多行添加到另一个 table
Adding multiple rows of a table to another table
我有一个 table 如下:(这是我的 table 中的几行)
T = table({'A';'A';'A';'B';'B';'B';'C';'C';'C';'C'}, {'x';'y';'z';'x';'w';'t';'z';'x';'t';'o'},[5;1;2;2;4;2;2;5;4;1], ...
'VariableNames', {'memberId', 'productId','Rating'});
T:
A x 5
A y 1
Z z 2
B x 2
B w 4
B t 2
C z 2
C x 5
C t 4
C o 1
C u 3
D r 1
D t 2
D w 5
.
.
.
.
我需要带用户 A 然后创建一个 table 就像以前的 table (Table T) 并且所有行都与用户 A 相关以输入 table.At这一点在table有以下几行:
A x 5
A y 1
A z 2
接下来,考虑与该用户相关的产品,即 x,y,z 。然后所有包含 x,然后是 y 和 z 的行都添加到 table。此时 table 中有以下几行:
A x 5
A y 1
A z 2
B x 2
C z 2
C x 5
然后,其他用户已添加到 table 以考虑,即 B,C。然后为第一个用户 (A) 做同样的事情,为这个用户做同样的事情(分别为 B 然后 C)。
这样做是为了在 table 中添加所需的行数。例如,这里需要 8 行。即最终结果如下:
A x 5
A y 1
A z 2
B x 2
C z 2
C x 5
B w 4
B t 2
即工作完成后,第二 table 行中请求的行数将被导入。
如果有人在这方面帮助我,我将不胜感激。
这是一种完成您所要求的方法(尽管您的问题中有些情况没有明确定义):
% I added user 'D' for the scenario of an unconnected node
T = table({'A';'A';'A';'B';'B';'B';'C';'C';'C';'C';'D';'D';'D';'D'},...
{'x';'y';'z';'x';'w';'t';'z';'x';'t';'o';'q';'p';'f';'v'},...
[5;1;2;2;4;2;2;5;4;1;4;5;2;1], ...
'VariableNames', {'memberId', 'productId','Rating'});
% initial preparations:
rows_limit = 8;
first_user = 'B'; % this is just for readability
newT = table(cell(rows_limit,1),cell(rows_limit,1),zeros(rows_limit,1),...
'VariableNames',{'memberId', 'productId','Rating'});
% We need an index vector so we won't add the same row twice:
added = false(height(T),1);
row_count = 1;
users_list = {first_user};
% now we start adding rows to newT until it's full:
while row_count<rows_limit
while numel(users_list)>=1
% get all the user's rows
next_to_add = strcmp(T.memberId,users_list{1}) & ~added;
% if this user has any rows to be added:
if sum(next_to_add)>0
% if there's enough empty rows in newT add them to it:
if sum(next_to_add) <= rows_limit-row_count+1
newT(row_count:row_count+sum(next_to_add)-1,:) = T(next_to_add,:)
% and update the index vector:
added = added | strcmp(T.memberId,users_list{1});
else
% otherwise - fill the empty rows and quit the loop:
if row_count <= rows_limit
end_to_add = find(next_to_add,rows_limit-row_count+1);
newT(row_count:rows_limit,:) = T(end_to_add,:)
end
row_count = rows_limit+1; % to exit the outer loop
break
end
row_count = row_count+sum(next_to_add);
% Add related products:
% ====================
% save the first new user to be addaed by related products:
last_user_row = row_count;
% get all the products we already added to newT:
products = unique(newT.productId(1:row_count-1),'stable');
% although we want only the last user products, because we add all the
% products the before, our index vector ('added') will eliminate them
for p = 1:numel(products)
% get all the product's rows
next_to_add = strcmp(T.productId,products{p}) & ~added;
% if there's enough empty rows in newT add them to it:
if sum(next_to_add)>0
if sum(next_to_add) <= rows_limit-row_count+1
newT(row_count:row_count+sum(next_to_add)-1,:) = T(next_to_add,:);
% and update the index vector:
added = added | strcmp(T.productId,products{p});
else
% otherwise - fill the empty rows and quit the loop:
if row_count <= rows_limit
end_to_add = find(next_to_add,rows_limit-row_count+1);
newT(row_count:rows_limit,:) = T(end_to_add,:);
end
row_count = rows_limit+1; % to exit the outer loop
break
end
end
row_count = row_count+sum(next_to_add);
end
end
% get the list of new users we just added, and concat to the users
% left in the original list:
users_list = [unique(newT.memberId(last_user_row:row_count-1),'stable');
unique(T.memberId(~added),'stable')];
end
end
给出 newT
:
memberId productId Rating
________ _________ ______
'B' 'x' 2
'B' 'w' 4
'B' 't' 2
'A' 'x' 5
'C' 'x' 5
'C' 't' 4
'A' 'y' 1
'A' 'z' 2
在此实现中,行是逐个用户和逐个产品添加的,如果要添加的下一个 user/product 的行数多于 newT
中可用的行数,那么我们添加与我们 cen 一样多的行,直到我们到达 rows_limit
然后循环退出。
所以对于 rows_limit = 4;
,你会得到 newT
作为:
memberId productId Rating
________ _________ ______
'B' 'x' 2
'B' 'w' 4
'B' 't' 2
'A' 'x' 5
只要用户之间存在联系,那么每个用户的相关产品都会为列表带来新用户,循环继续 newT
中的新用户。但是,可能我们从一个节点开始,并非所有其他节点都是其网络的一部分。例如,看看下面的图表,它说明了我在上面的代码中使用的扩展示例中的连接:
节点 D
未连接到所有其他节点,因此除非我们在 T
中积极寻找新的不相关用户,否则我们将永远无法到达它。上面的实现确实在寻找这种用户。
我有一个 table 如下:(这是我的 table 中的几行)
T = table({'A';'A';'A';'B';'B';'B';'C';'C';'C';'C'}, {'x';'y';'z';'x';'w';'t';'z';'x';'t';'o'},[5;1;2;2;4;2;2;5;4;1], ...
'VariableNames', {'memberId', 'productId','Rating'});
T:
A x 5
A y 1
Z z 2
B x 2
B w 4
B t 2
C z 2
C x 5
C t 4
C o 1
C u 3
D r 1
D t 2
D w 5
.
.
.
.
我需要带用户 A 然后创建一个 table 就像以前的 table (Table T) 并且所有行都与用户 A 相关以输入 table.At这一点在table有以下几行:
A x 5
A y 1
A z 2
接下来,考虑与该用户相关的产品,即 x,y,z 。然后所有包含 x,然后是 y 和 z 的行都添加到 table。此时 table 中有以下几行:
A x 5
A y 1
A z 2
B x 2
C z 2
C x 5
然后,其他用户已添加到 table 以考虑,即 B,C。然后为第一个用户 (A) 做同样的事情,为这个用户做同样的事情(分别为 B 然后 C)。 这样做是为了在 table 中添加所需的行数。例如,这里需要 8 行。即最终结果如下:
A x 5
A y 1
A z 2
B x 2
C z 2
C x 5
B w 4
B t 2
即工作完成后,第二 table 行中请求的行数将被导入。
如果有人在这方面帮助我,我将不胜感激。
这是一种完成您所要求的方法(尽管您的问题中有些情况没有明确定义):
% I added user 'D' for the scenario of an unconnected node
T = table({'A';'A';'A';'B';'B';'B';'C';'C';'C';'C';'D';'D';'D';'D'},...
{'x';'y';'z';'x';'w';'t';'z';'x';'t';'o';'q';'p';'f';'v'},...
[5;1;2;2;4;2;2;5;4;1;4;5;2;1], ...
'VariableNames', {'memberId', 'productId','Rating'});
% initial preparations:
rows_limit = 8;
first_user = 'B'; % this is just for readability
newT = table(cell(rows_limit,1),cell(rows_limit,1),zeros(rows_limit,1),...
'VariableNames',{'memberId', 'productId','Rating'});
% We need an index vector so we won't add the same row twice:
added = false(height(T),1);
row_count = 1;
users_list = {first_user};
% now we start adding rows to newT until it's full:
while row_count<rows_limit
while numel(users_list)>=1
% get all the user's rows
next_to_add = strcmp(T.memberId,users_list{1}) & ~added;
% if this user has any rows to be added:
if sum(next_to_add)>0
% if there's enough empty rows in newT add them to it:
if sum(next_to_add) <= rows_limit-row_count+1
newT(row_count:row_count+sum(next_to_add)-1,:) = T(next_to_add,:)
% and update the index vector:
added = added | strcmp(T.memberId,users_list{1});
else
% otherwise - fill the empty rows and quit the loop:
if row_count <= rows_limit
end_to_add = find(next_to_add,rows_limit-row_count+1);
newT(row_count:rows_limit,:) = T(end_to_add,:)
end
row_count = rows_limit+1; % to exit the outer loop
break
end
row_count = row_count+sum(next_to_add);
% Add related products:
% ====================
% save the first new user to be addaed by related products:
last_user_row = row_count;
% get all the products we already added to newT:
products = unique(newT.productId(1:row_count-1),'stable');
% although we want only the last user products, because we add all the
% products the before, our index vector ('added') will eliminate them
for p = 1:numel(products)
% get all the product's rows
next_to_add = strcmp(T.productId,products{p}) & ~added;
% if there's enough empty rows in newT add them to it:
if sum(next_to_add)>0
if sum(next_to_add) <= rows_limit-row_count+1
newT(row_count:row_count+sum(next_to_add)-1,:) = T(next_to_add,:);
% and update the index vector:
added = added | strcmp(T.productId,products{p});
else
% otherwise - fill the empty rows and quit the loop:
if row_count <= rows_limit
end_to_add = find(next_to_add,rows_limit-row_count+1);
newT(row_count:rows_limit,:) = T(end_to_add,:);
end
row_count = rows_limit+1; % to exit the outer loop
break
end
end
row_count = row_count+sum(next_to_add);
end
end
% get the list of new users we just added, and concat to the users
% left in the original list:
users_list = [unique(newT.memberId(last_user_row:row_count-1),'stable');
unique(T.memberId(~added),'stable')];
end
end
给出 newT
:
memberId productId Rating
________ _________ ______
'B' 'x' 2
'B' 'w' 4
'B' 't' 2
'A' 'x' 5
'C' 'x' 5
'C' 't' 4
'A' 'y' 1
'A' 'z' 2
在此实现中,行是逐个用户和逐个产品添加的,如果要添加的下一个 user/product 的行数多于 newT
中可用的行数,那么我们添加与我们 cen 一样多的行,直到我们到达 rows_limit
然后循环退出。
所以对于 rows_limit = 4;
,你会得到 newT
作为:
memberId productId Rating
________ _________ ______
'B' 'x' 2
'B' 'w' 4
'B' 't' 2
'A' 'x' 5
只要用户之间存在联系,那么每个用户的相关产品都会为列表带来新用户,循环继续 newT
中的新用户。但是,可能我们从一个节点开始,并非所有其他节点都是其网络的一部分。例如,看看下面的图表,它说明了我在上面的代码中使用的扩展示例中的连接:
节点 D
未连接到所有其他节点,因此除非我们在 T
中积极寻找新的不相关用户,否则我们将永远无法到达它。上面的实现确实在寻找这种用户。