我在matlab中有以下格式的文件:
user_id_a: (item_1,rating),(item_2,rating),...(item_n,rating)
user_id_b: (item_25,rating),(item_50,rating),...(item_x,rating)
....
....
因此每行的值都以冒号分隔,冒号左边的值是表示user_id的数字,右边的值是item_ids(也是数字)和等级(数字不是浮点数)的元组。
我想将这些数据读入matlab单元阵列或更好地最终将其转换为稀疏矩阵,其中user_id表示行索引,item_id表示列索引并将相应的评级存储在该数组索引中。 (这可以工作,因为我先前知道我的宇宙中的用户和项目的数量,因此ID不能大于此。)
任何帮助都将不胜感激。
我到目前为止尝试了文本扫描功能如下:
c = textscan(f,'%d %s','delimiter',':') %this creates two cells one with all the user_ids
%and another with all the remaining string values.
现在,如果我尝试执行类似str2mat(c{2})
的操作,它可以工作,但它也会在矩阵中存储'('和')'字符。我想以我上面描述的方式存储一个稀疏矩阵。
我是matlab的新手,对此事感兴趣。
答案 0 :(得分:1)
f = fopen('data.txt','rt'); %// data file. Open as text ('t')
str = textscan(f,'%s'); %// gives a cell which contains a cell array of strings
str = str{1}; %// cell array of strings
r = str(1:2:end);
r = cellfun(@(s) str2num(s(1:end-1)), r); %// rows; numeric vector
pairs = str(2:2:end);
pairs = regexprep(pairs,'[(,)]',' ');
pairs = cellfun(@(s) str2num(s(1:end-1)), pairs, 'uni', 0);
%// pairs; cell array of numeric vectors
cols = cellfun(@(x) x(1:2:end), pairs, 'uni', 0);
%// columns; cell array of numeric vectors
vals = cellfun(@(x) x(2:2:end), pairs, 'uni', 0);
%// values; cell array of numeric vectors
rows = arrayfun(@(n) repmat(r(n),1,numel(cols{n})), 1:numel(r), 'uni', 0);
%// rows repeated to match cols; cell array of numeric vectors
matrix = sparse([rows{:}], [cols{:}], [vals{:}]);
%// concat rows, cols and vals into vectors and use as inputs to sparse
对于示例文件
1: (1,3),(2,4),(3,5)
10: (1,1),(2,2)
这给出了以下稀疏矩阵:
matrix =
(1,1) 3
(10,1) 1
(1,2) 4
(10,2) 2
(1,3) 5
答案 1 :(得分:0)
我认为较新版本的Matlab有一个stringsplit函数,使得这种方法过度,但如果不是很快,以下工作。它将文件拆分为用户ID和显示的“其他内容”,初始化一个大的空矩阵,然后遍历其他内容,将其拆分并放置在矩阵中的正确位置。
(当我出于某种原因打开它时,我没有看到之前的答案 - 它比这个更复杂,尽管这可能更容易遵循,但代价是缓慢)。如果间距不一致,我会将\s*
放入正则表达式中,否则在数据健全性检查方面不会有太大作用。输出是完整数组,如果需要,您可以将其转换为稀疏数组。
% matlab_test.txt:
% 101: (1,42),(2,65),(5,0)
% 102: (25,78),(50,12),(6,143),(2,123)
% 103: (23,6),(56,3)
clear all;
fclose('all');
% your path will vary, of course
file = '<path>/matlab_test.txt';
f = fopen(file);
c = textscan(f,'%d %s','delimiter',':');
celldisp(c)
uids = c{1}
tuples = c{2}
% These are stated as known
num_users = 3;
num_items = 40;
desired_array = zeros(num_users, num_items);
expression = '\((\d+)\s*,\s*(\d+)\)'
% Assuming length(tuples) == num_users for simplicity
for k = 1:num_users
uid = uids(k)
tokens = regexp(tuples{k}, expression, 'tokens');
for l = 1:length(tokens)
item_id = str2num(tokens{l}{1})
rating = str2num(tokens{l}{2})
desired_array(uid, item_id) = rating;
end
end