2014-02-25 117 views
3

我有以下列格式中的matlab一个文件: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(也是数字)和rating(数字不是浮动)的元组。

我想将这些数据读入一个matlab单元格数组或更好,但最终将其转换为稀疏矩阵,其中user_id表示行索引,item_id表示列索引并将相应的评级存储在该数组索引中。 (这工作,我知道用户和项目的在我的宇宙先验的号码,以便IDS不能大于)。

任何帮助,将不胜感激。

我迄今尝试textscan功能如下:

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

每行的(项目,评级)对的数量是否固定? –

+0

NO它是可变的,但每一个元组由逗号分隔的“” – anonuser0428

回答

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 
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