2015-03-05 3 views
1

У меня есть следующий код отрезал который работает, но невероятно медленно:накапливались массив в Matlab

bps = [5; 10; 15; 20] 
src = ['10.0.0.1'; '10.0.0.2'; '10.0.0.1'; '10.0.0.2'] 

uniqueSrc = unique(src); 

sumBps = []; 
for i=1:length(uniqueSrc) 
    indy=find(ismember(src,uniqueSrc(i))); 
    sumBps = [sumBps; sum(bps(indy))]; 
end 

uniqueSrc = ['10.0.0.1'; '10.0.0.2'] 
sumBps = [20; 30] 

ЦСИ массив ячеек, содержащий IP-адреса в то время как один IP может происходить несколько раз. Он считывается из файла с текстом и% s. bps содержит целые числа.

Мне нужно суммировать все целые числа в bps, принадлежащие одному и тому же IP-адресу в src. Соответствие соответствует индексам. Таким образом, src (1) является IP-адресом bps (1) и т. Д.

Результатом должно быть соответствие IP-адресов сумме соответствующих значений бит. Таким образом, uniqueSrc (1) - это IP, который имеет sumBps (1), который является суммой всех значений bps, принадлежащих определенному IP.

Хотя мой код, безусловно, работает, он очень неэффективен, как мне кажется, и мне интересно, какой будет знаменитый однострочный матлаб для решения этой проблемы.

Заранее благодарен!

Редактировать: Добавлен пример ввода и вывода.

+0

Post небольшой пример ввода и требуемый выходной –

+1

вход будет хорошо. Как вы храните свои IP-адреса? – eigenchris

ответ

4

Классический использование accumarray:

%// Your inputs 
bps = [5; 10; 15; 20]; 
src = ['10.0.0.1'; '10.0.0.2'; '10.0.0.1'; '10.0.0.2']; 

%// Relevant code 
[uniqueSrc,~,id] = unique(cellstr(src)); 
sumBps = accumarray(id, bps); 

Приведенный выше код, вероятно, заслуживает некоторого пояснения. accumarray - функция, которая объединяет или группирует данные вместе на основе идентификаторов. Таким образом, я сделал то, что я преобразовал src в массив ячеек с cellstr, а затем использовал unique, чтобы получить список всех уникальных IP-адресов в дополнение к назначению уникального идентификатора для каждого IP-адреса. Уникальные IP-адреса хранятся в uniqueSrc, который является первым выходом unique, и каждому IP-адресу в src присваивается уникальный идентификатор, хранящийся в id. Сложность, о которой мало кто думает, заключается в том, что unique не только находит уникальные записи в массиве, но также возвращает эти значения отсортировано. Из этого отсортированного результата идентификаторы, назначенные каждому элементу в src, будут следовать этому соглашению о заказе. Поскольку вы хотите вернуть эти IP-адреса по порядку (похоже, это так), нам не нужно думать об этой части. Кроме того, мне нужно было преобразовать ваши IP-адреса в массив ячеек, чтобы это работало.

Как только мы определяем их, мы используем accumarray, где первый элемент является идентификатором для каждого IP-адреса, а второй элемент - это то, к какому значению относится каждый IP-адрес. По умолчанию accumarray заполняет те значения, которые имеют один и тот же идентификатор, и суммы все они. Это в значительной степени описывает, что именно вы хотите сделать.

Выход я для требуемых переменных:

>> uniqueSrc 

uniqueSrc = 

    '10.0.0.1' 
    '10.0.0.2' 

>> sumBps 

sumBps = 

    20 
    30 
+0

@eigenchris - Я не уверен, что мое редактирование появилось до или после вашего комментария lol. – rayryeng

+0

Я тоже не, ха-ха. Я удалил его в любом случае. Хороший ответ. – eigenchris

+0

Название kinda отдает его :-). Почти опубликован, но он искал привязку адресов и суммировал значения бит в строках. –

1

Добавить свой ответ, потому что я хотел показать, как сцеплять IP-адреса и суммируется бит, плюс вам не нужно преобразовать в ячейку, если вы используете опцию rows с unique:

bps = [5; 10; 15; 20] 
src = ['10.0.0.1'; '10.0.0.2'; '10.0.0.1'; '10.0.0.2']; 

[strng ii jj]= unique(src,'rows'); 


strcat({strng},{char(32)*ones(size(strng,1),1)},{num2str(accumarray(jj,bps))}) 
+0

OH! Хорошая работа с флагом 'rows'! – rayryeng

+0

@rayryeng Да, но, как правило, лучше работать с массивами ячеек, если ваши строки всегда равны по длине, что не является гарантией. –

+0

Вот почему я решил пойти с камерами. Это, конечно, игрушечный корпус, но я бы, конечно, придерживался клеток для строк переменной длины. Хорошо идет! – rayryeng

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