تشكيل مصفوفة هوية "جزئية" وفقًا لمتجه مملوء جزئيًا

2

أقوم حاليًا بتشكيل مصفوفة من ناقل في MATLAB باتباع المخطط الموضح أدناه:

تعطى ناقلات x تحتوي على الآحاد والأصفار في أمر تعسفي ، على سبيل المثال

x = [0 1 1 0 1]; 

من هذا ، أود أن أشكل مصفوفة Y الموصوفة كما يلي:

  • Y لديها m الصفوف ، أين m هو عدد الأشخاص في x (هنا: 3 ).
  • كل صف من Y مليء بواحد في k -الدخل ، أين k هو موضع واحد في المتجه x (هنا: k = 2,3,5 )
  • على سبيل المثال x من فوق ، سيؤدي ذلك إلى:

    Y = [0 1 0 0 0;
         0 0 1 0 0; 
         0 0 0 0 1]
    

    هذا مطابق لمصفوفة هوية لها ( x=0 ) تم إلغاء الصفوف.

أحقق ذلك حاليًا عبر الرمز التالي:

x = [0,1,1,0,1]; %example from above
m = sum(x==1);
Y = zeros(m,numel(x));
p = 1;
for n = 1:numel(x)
    if x(n) == 1 
       Y(p,n) = 1;
       p = p+1;
    end  
end

إنه يعمل ولكني غير راضٍ نوعًا ما لأنه يبدو غير فعال وغير دقيق إلى حد ما. نرحب بأي أفكار لتنفيذ أكثر سلاسة ، ربما باستخدام بعض مضاعفات المصفوفة أو نحو ذلك.

5 الردود

5
افضل جواب

إليك بعض البدائل المكونة من سطر واحد:

  • باستخدام sparse :

    Y = full(sparse(1:nnz(x), find(x), 1));
    
  • مماثلة ولكن مع accumarray :

    Y = accumarray([(1:nnz(x)).' find(x(:))], 1);
    
  • باستخدام eye والفهرسة. يفترض هذا Y غير معرّف سابقًا:

    Y(:,logical(x)) = eye(nnz(x));
    
:مؤلف
4
افضل جواب

إليك بديل باستخدام مضاعفات المصفوفة:

x = [0,1,1,0,1];
I = eye(numel(x));

% construct identity matrix with zero rows
Y = I .* x;   % uses implicit expansion from 2016b or later
Y = Y(logical(x), :);   % take only non-zero rows of Y

نتيجة:

Y =
   0   1   0   0   0
   0   0   1   0   0
   0   0   0   0   1

بفضل تعليق @ SardarUsama لتبسيط الرمز قليلاً.

:مؤلف
4
افضل جواب

استعمال find للحصول على مؤشرات في x والتي هي أيضًا أعمدة من تلك الموجودة في Y . أوجد عدد صفوف Y بإضافة جميع عناصر المتجه x . استخدم هذه لتهيئة Y كمصفوفة صفرية . الآن ابحث عن المؤشرات الخطية لوضع 1s باستخدام sub2ind . استخدم هذه المؤشرات لتغيير عناصر Y إلى 1.

cols = find(x);
noofones = sum(x);
Y = zeros(noofones, size(x,2));
Y(sub2ind(size(Y), 1:noofones, cols)) = 1;
:مؤلف
1
افضل جواب

من تعليقك "هذا مطابق لمصفوفة هوية تم حذف صفوفها (س = 0)" ، حسنًا ، يمكنك أيضًا إنشاؤها بشكل صريح على هذا النحو:

Y = eye(length(x));
Y(x==0, :) = [];

خيار بطيء للغاية لفترة طويلة x ، لكنه يعمل بشكل أسرع قليلاً من full(sparse(... إلى عن على x مع 10 عناصر على جهاز الكمبيوتر الخاص بي.

:مؤلف
1
افضل جواب

شكرا للجميع على البدائل اللطيفة! لقد جربت جميع حلولك ومتوسط مرات التنفيذ على تنفيذ 1e4 من أجل متجهات x (1000 إدخال) عشوائية. ها هي النتائج:

  1. (7.3e-4 ثانية) full(sparse(1:nnz(x), find(x), 1));
  2. (7.5e-4 ثانية) cols = find(x); noofones = sum(x); Y = zeros(noofones, size(x,2)); Y(sub2ind(size(Y), 1:noofones, cols)) = 1;
  3. (7.7e-4 ثانية) Y = accumarray([(1:nnz(x)).' find(x(:))], 1);
  4. (1.7e-3 ثانية) I = speye(numel(x)); Y = I .* x; Y = full(Y(logical(x), :));
  5. (3.1e-3 ثانية) Y(:,logical(x)) = eye(nnz(x));
:مؤلف
فوق
قائمة طعام