2013-06-10 4 views
3

Я пытаюсь читать данные из текстового файла. Я могу сделать это через импорт. Он работает нормально. Мои данные импортированные как: UserID | SportID | РейтингMatlab обрабатывает данные из текстового файла

Есть много пользователей, которые могут, как и любой вид спорта с любым рейтингом, например:

User|SportID|Rating 
1  2  10 
1  3  5 
2  1  10 
2  3  2 

я пытаюсь создать новую матрицу, как показано ниже

UserID Sport1 Sport2 Sport3 
1  (null) 10  5 
2  10 (null) 2 

Я попытался сделать это через «для» и «петлю», однако есть почти 2000 пользователей и 1000 видов спорта, а их данные - почти 100000. Как я могу это сделать?

+0

Если у вас есть параллельная обработка, вы можете использовать цикл 'parfor'. – KronoS

+1

Какая у вас проблема? Это слишком медленно? У вас не хватает памяти? Ваша проблема заключается в создании вашей матрицы или в поиске вещей? –

+0

Это было слишком медленно .. но я использовал kronos ответ, это работает как шарм :) – Palindrom

ответ

1

Вы можете сделать следующее:

% Test Input 
inputVar = [1 2 10; 1 3 5; 2 1 10; 2 3 2]; 

% Determine number of users, and sports to create the new table 
numSports = max(inputVar(1:end,2)); 
numUsers = max(inputVar(1:end,1)); 
newTable = NaN(numUsers, numSports); 

% Iterate for each row of the new table (# of users) 
for ii = 1:numUsers 
    % Determine where the user rated from input mat, which sport he/she rated, and the rating 
    userRating = find(inputVar(1:end,1) == ii); 
    sportIndex = inputVar(userRating, 2)'; 
    sportRating = inputVar(userRating, 3)'; 
    newTable(ii, sportIndex) = sportRating; % Crete the new table based on the ratings. 
end 

newTable 

который произвел следующее:

newTable = 

    NaN 10  5 
    10 NaN  2 

Это будет только бежать на количество пользователей, которые во входной таблице.

+0

Его работа как я хочу .. большое спасибо – Palindrom

+0

@MichaelAdam: Привет, У меня вопрос: aren ' t 'sub2ind' или' accarray' быстрее, чем этот метод? или «редкой». Можете ли вы объяснить, почему вы выбрали этот метод? – pm89

+1

@ pm89, возможно, это легче понять ответ. Ваш ответ, хотя он может быть и быстрее, немного сбивает с толку. – KronoS

2

Чтобы сделать это быстро, вы можете использовать разреженную матрицу с одним размером UserID, а другой Sports. Редкая матрица будет вести себя для большинства вещей, таких как нормальная матрица. Построить его, как так

out = sparse(User, SportID, Rating) 

где User, SportID и Rating векторы, соответствующие столбцам текстового файла.

Примечание 1: для дубликатов User и SportID сумма Rating будет суммирована.

Примечание 2: пустые записи, которые были записаны как (null) в вопросе, не хранятся в разреженных матрицах, а только ненулевые (то есть основная точка разреженных матриц).

+0

Большое спасибо .. – Palindrom

1

Я полагаю, что вы уже определили null как номер для упрощения.

Null = -1; % or any other value which could not be a rating. 

Учитывая:

nSports = 1000; % Number of sports 
nUsers = 2000; % Number of users 

Предварительно выделить результат:

Rating_Mat = ones(nUsers, nSports) * Null; % Pre-allocation 

затем использовать sub2ind (по аналогии с this answer):

Rating_Mat (sub2ind([nUsers nSports], User, SportID) = Rating; 

O г accumarray:

Rating_Mat = accumarray([User, SportID], Rating); 

при условии, что User и SportID являются Nx1.

Надеюсь, это поможет.

Смежные вопросы