मैं MATLAB में मैट्रिक्स की प्रत्येक पंक्ति / स्तंभ के लिए एक फ़ंक्शन कैसे लागू कर सकता हूं?


106

आप वेक्टर में प्रत्येक आइटम के लिए एक फ़ंक्शन लागू कर सकते हैं, उदाहरण के लिए v + 1, या आप फ़ंक्शन का उपयोग कर सकते हैं arrayfun। लूप का उपयोग किए बिना मैं मैट्रिक्स की प्रत्येक पंक्ति / स्तंभ के लिए कैसे कर सकता हूं?

जवाबों:


73

कई अंतर्निहित ऑपरेशन जैसे कि sumऔर prodपहले से ही पंक्तियों या स्तंभों में काम करने में सक्षम हैं, इसलिए आप इस फ़ंक्शन का लाभ उठाने में सक्षम हो सकते हैं जिसका आप लाभ उठा सकते हैं।

यदि यह एक व्यवहार्य विकल्प नहीं है, एक तरह से इसे का उपयोग पंक्तियों या स्तंभों कोशिकाओं में एकत्र करने के लिए है करने के लिए mat2cellया num2cell, तो का उपयोग cellfunजिसके परिणामस्वरूप सेल सरणी पर संचालित करने के लिए।

एक उदाहरण के रूप में, मान लें कि आप मैट्रिक्स के कॉलम को योग करना चाहते हैं M। आप इसे केवल उपयोग करके कर सकते हैं sum:

M = magic(10);           %# A 10-by-10 matrix
columnSums = sum(M, 1);  %# A 1-by-10 vector of sums for each column

और यहां बताया गया है कि अधिक जटिल num2cell/ cellfunविकल्प का उपयोग करके आप ऐसा कैसे करेंगे :

M = magic(10);                  %# A 10-by-10 matrix
C = num2cell(M, 1);             %# Collect the columns into cells
columnSums = cellfun(@sum, C);  %# A 1-by-10 vector of sums for each cell

17
मैं सरल-लूप के खिलाफ किसी विशेष मामले के लिए इस दृष्टिकोण के प्रदर्शन का परीक्षण करूंगा, जो तब तेजी से हो सकता है जो मैट्रिक्स को सेल सरणी में परिवर्तित कर सकता है। परीक्षण करने के लिए टिक / टैक रैप का उपयोग करें।
युक

5
@ युक: मुझे लगता है कि आपका मतलब "टिक / टो" था। ;)
gnovice

4
@gnovice, शायद yuk ने कुछ जादू किया और tak = toc को असाइन किया। एक भाषा में, जहाँ true = falseएक मान्य कथन है, मुझे यकीन है कि वहाँ एक तरीका है जो आप इसे कर सकते हैं: (
शतरंज

1
@Argyll: यह निर्धारित करना कि कौन सा दृष्टिकोण अधिक कुशल है, यह इस बात पर निर्भर करेगा कि आप किस प्रकार के फ़ंक्शन को लागू करना चाहते हैं, मैट्रिक्स का आकार, आदि। संक्षेप में, यह समस्या-आश्रित है। वास्तव में, कभी-कभी लूप के लिए एक अच्छा पुराना सबसे तेज़ विकल्प हो सकता है।
14

2
@gnovice, मैं सुझाव देता हूं कि इसे संपादित करें sum(M, 1)। शुरुआती सोच sumसकते हैं कि इस तरह से मनमाने आकार के मैट्रिस के लिए इस्तेमाल किया जा सकता है और फिर मैट्रिक्स एक दिन होने पर स्टंप हो जाता है 1-by-n
स्टीवी ग्रिफिन

24

आप अधिक अस्पष्ट Matlab फ़ंक्शन bsxfun चाहते हैं । मैटलैब डॉक्यूमेंटेशन से, bsxfun ", ए-बी को एंरल्स और बी को सिंगल-एलिमेंट बाइनरी ऑपरेशन द्वारा निर्दिष्ट करता है, जो सिंगलटन एसेलेबल्स एनेबल्ड एनेबल्ड एनेबल्ड एनेबल है।"

@gnovice उस राशि के ऊपर कहा गया है और अन्य बुनियादी फ़ंक्शन पहले से ही पहले गैर-सिंगलटन आयाम (यानी, पंक्तियों में एक से अधिक पंक्ति, कॉलम, यदि केवल एक पंक्ति या उच्च आयाम हैं, तो निचले आयाम सभी में == 1 पर काम करते हैं) )। हालाँकि, bsxfun किसी भी फ़ंक्शन के लिए काम करता है, जिसमें (और विशेष रूप से) उपयोगकर्ता-परिभाषित फ़ंक्शन शामिल हैं।

उदाहरण के लिए, मान लें कि आपके पास एक मैट्रिक्स A और एक पंक्ति वेक्टर BEg है, आइए बताते हैं:

A = [1 2 3;
     4 5 6;
     7 8 9]
B = [0 1 2]

आप एक फ़ंक्शन पॉवर_बाइ_कोल चाहते हैं जो बी के संगत कॉलम की शक्ति ए में सभी तत्वों को वेक्टर सी में लौटाता है।

उपरोक्त उदाहरण से, C एक 3x3 मैट्रिक्स है:

C = [1^0 2^1 3^2;
     4^0 5^1 6^2;
     7^0 8^1 9^2]

अर्थात,

C = [1 2 9;
     1 5 36;
     1 8 81]

आप इसे दमन बल का उपयोग करके कर सकते हैं:

C = A.^repmat(B, size(A, 1), 1)

या आप इसे bsxfun का उपयोग करके उत्तम दर्जे का कर सकते हैं, जो आंतरिक रूप से repmat कदम का ध्यान रखता है:

C = bsxfun(@(x,y) x.^y, A, B)

तो bsxfun आपको कुछ कदम बचाता है (आपको A के आयामों की स्पष्ट रूप से गणना करने की आवश्यकता नहीं है)। हालांकि, मेरा कुछ अनौपचारिक परीक्षणों में, यह पता चला है कि यदि फ़ंक्शन लागू किया जाना है (जैसे मेरी शक्ति फ़ंक्शन, ऊपर) सरल है, तो repmat लगभग दो बार उपवास करता है। इसलिए आपको यह चुनने की आवश्यकता होगी कि आप सादगी चाहते हैं या गति।


21

मैं इस पर टिप्पणी नहीं कर सकता कि यह कितना कुशल है, लेकिन यहाँ एक समाधान है:

applyToGivenRow = @(func, matrix) @(row) func(matrix(row, :))
applyToRows = @(func, matrix) arrayfun(applyToGivenRow(func, matrix), 1:size(matrix,1))'

% Example
myMx = [1 2 3; 4 5 6; 7 8 9];
myFunc = @sum;

applyToRows(myFunc, myMx)

अधिक सामान्य उत्तर यहां दिया गया है
वोक

11

एलेक्स के जवाब पर निर्माण , यहाँ एक अधिक सामान्य कार्य है:

applyToGivenRow = @(func, matrix) @(row) func(matrix(row, :));
newApplyToRows = @(func, matrix) arrayfun(applyToGivenRow(func, matrix), 1:size(matrix,1), 'UniformOutput', false)';
takeAll = @(x) reshape([x{:}], size(x{1},2), size(x,1))';
genericApplyToRows = @(func, matrix) takeAll(newApplyToRows(func, matrix));

यहाँ दो कार्यों के बीच तुलना है:

>> % Example
myMx = [1 2 3; 4 5 6; 7 8 9];
myFunc = @(x) [mean(x), std(x), sum(x), length(x)];
>> genericApplyToRows(myFunc, myMx)

ans =

     2     1     6     3
     5     1    15     3
     8     1    24     3

>> applyToRows(myFunc, myMx)
??? Error using ==> arrayfun
Non-scalar in Uniform output, at index 1, output 1.
Set 'UniformOutput' to false.

Error in ==> @(func,matrix)arrayfun(applyToGivenRow(func,matrix),1:size(matrix,1))'

6

पूर्णता / रुचि के लिए मैं जोड़ना चाहूंगा कि मैटलैब में एक फ़ंक्शन है जो आपको प्रति-तत्व के बजाय डेटा प्रति पंक्ति पर संचालित करने की अनुमति देता है। इसे rowfun( http://www.mathworks.se/help/matlab/ref/rowfun.html ) कहा जाता है , लेकिन एकमात्र "समस्या" यह है कि यह तालिकाओं ( http://www.mathworks.se/help/) पर काम करता है matlab / रेफरी / table.html ) के बजाय मैट्रिक्स


4

इस प्रश्न के उत्तर की विकसित प्रकृति को जोड़ते हुए, r2016b से शुरू करके, MATLAB bsxfunकई मामलों में आवश्यकता को हटाते हुए, एकल आयामों का विस्तार करेगा ।

से r2016b रिलीज नोट्स :

निहित विस्तार: लंबाई 1 के आयामों के स्वचालित विस्तार के साथ सरणियों के लिए तत्व-वार संचालन और कार्यों को लागू करें

व्यापक विस्तार अदिश विस्तार का सामान्यीकरण है। स्केलर विस्तार के साथ, एक स्केलर तत्व-वार संचालन को सुविधाजनक बनाने के लिए एक और सरणी के समान आकार का विस्तार करता है। निहित विस्तार के साथ, यहां सूचीबद्ध तत्व-वार ऑपरेटर और फ़ंक्शन समान रूप से अपने इनपुट का विस्तार कर सकते हैं, जब तक कि सरणियों में संगत आकार होते हैं। दो सरणियों के संगत आकार हैं यदि, प्रत्येक आयाम के लिए, इनपुट के आयाम आकार या तो समान हैं या उनमें से एक है। 1. अधिक जानकारी के लिए बुनियादी संचालन और सरणी बनाम मैट्रिक्स संचालन के लिए संगत सरणी आकार देखें।

Element-wise arithmetic operators+, -, .*, .^, ./, .\

Relational operators<, <=, >, >=, ==, ~=

Logical operators&, |, xor

Bit-wise functionsbitand, bitor, bitxor

Elementary math functionsmax, min, mod, rem, hypot, atan2, atan2d

उदाहरण के लिए, आप मैट्रिक्स A में प्रत्येक स्तंभ के माध्य की गणना कर सकते हैं, और फिर A - माध्य (A) के साथ प्रत्येक स्तंभ से माध्य मानों के वेक्टर को घटा सकते हैं।

पहले, यह कार्यक्षमता bsxfun फ़ंक्शन के माध्यम से उपलब्ध थी। अब यह अनुशंसा की जाती है कि आप bsxfun के अधिकांश उपयोगों को उन कार्यों और ऑपरेटरों के लिए सीधे कॉल के साथ बदलें जो अंतर्निहित विस्तार का समर्थन करते हैं। Bsxfun का उपयोग करने की तुलना में, अंतर्निहित विस्तार तेज गति, बेहतर मेमोरी उपयोग और कोड की बेहतर पठनीयता प्रदान करता है।


2

उपरोक्त में से किसी भी उत्तर ने मेरे लिए "बॉक्स से बाहर" काम नहीं किया, हालांकि, निम्नलिखित फ़ंक्शन, अन्य उत्तरों के विचारों को कॉपी करके प्राप्त किया गया है:

apply_func_2_cols = @(f,M) cell2mat(cellfun(f,num2cell(M,1), 'UniformOutput',0));

यह एक फ़ंक्शन लेता है fऔर इसे मैट्रिक्स के हर कॉलम पर लागू करता है M

उदाहरण के लिए:

f = @(v) [0 1;1 0]*v + [0 0.1]';
apply_func_2_cols(f,[0 0 1 1;0 1 0 1])

 ans =

   0.00000   1.00000   0.00000   1.00000
   0.10000   0.10000   1.10000   1.10000

1

मतलाब के हाल के संस्करणों के साथ, आप अपने लाभ के लिए तालिका डेटा संरचना का उपयोग कर सकते हैं। यहां तक ​​कि एक 'rowfun' ऑपरेशन भी है, लेकिन मुझे यह करना आसान लगता है:

a = magic(6);
incrementRow = cell2mat(cellfun(@(x) x+1,table2cell(table(a)),'UniformOutput',0))

या यहाँ एक पुराना है जो मेरे पास पुराने मैटलैब संस्करणों के लिए तालिकाओं की आवश्यकता नहीं है।

dataBinner = cell2mat(arrayfun(@(x) Binner(a(x,:),2)',1:size(a,1),'UniformOutput',0)')

1

ऐसा माना जाता है कि इसका उत्तर पहले कोशिकाओं में परिवर्तित होता है और फिर cellfunसभी कोशिकाओं पर काम करने के लिए उपयोग किया जाता है। मुझे विशिष्ट एप्लिकेशन का पता नहीं है, लेकिन सामान्य तौर पर मुझे लगता है bsxfunकि मैट्रिक्स को संचालित करने के लिए उपयोग करना अधिक कुशल होगा। मूल रूप से bsxfunदो सरणियों में एक ऑपरेशन तत्व-दर-तत्व लागू होता है। इसलिए यदि आप एक सरणी पाने के लिए वेक्टर n x 1में प्रत्येक आइटम को वेक्टर में प्रत्येक आइटम से गुणा करना चाहते हैं , तो आप उपयोग कर सकते हैं:m x 1n x m

vec1 = [ stuff ];    % n x 1 vector
vec2 = [ stuff ];    % m x 1 vector
result = bsxfun('times', vec1.', vec2);

यह आपको मैट्रिक्स देगा result, जिसमें (i, j) प्रविष्टि vec1, jth एलिमेंट द्वारा गुणा का ith तत्व होगा vec2

आप bsxfunसभी प्रकार के अंतर्निहित कार्यों के लिए उपयोग कर सकते हैं , और आप अपनी खुद की घोषणा कर सकते हैं। प्रलेखन में कई अंतर्निहित कार्यों की एक सूची है, लेकिन मूल रूप से आप किसी भी फ़ंक्शन का नाम दे सकते हैं जो दो सरणियों (वेक्टर या मैट्रिक्स) को तर्क के रूप में स्वीकार करता है और इसे काम करने के लिए मिलता है।


-1

एक मैट्रिक्स की पंक्ति योगों की गणना करने की मांग करते समय इस सवाल / जवाब पर ठोकर खाई।

मैं बस इतना जोड़ना चाहूंगा कि वास्तव में मैटलैब के SUM फ़ंक्शन में दिए गए आयाम के लिए योग का समर्थन है, अर्थात दो आयामों वाला एक मानक मैट्रिक्स।

तो कॉलम रकम की गणना करने के लिए:

colsum = sum(M) % or sum(M, 1)

और पंक्ति रकम के लिए, बस करो

rowsum = sum(M, 2)

मेरी शर्त है कि यह लूप के लिए प्रोग्रामिंग और कोशिकाओं में परिवर्तित होने की तुलना में तेज है :)

यह सब SUM के लिए matlab सहायता में पाया जा सकता है।


7
किसी दिए गए आयाम के साथ SUM को लागू करने की क्षमता का उल्लेख इस प्रश्न के मूल उत्तर के पहले वाक्य में किया गया था। जवाब तब मामले को संबोधित करने के लिए चला गया जब आयाम चुनने की क्षमता पहले से ही फ़ंक्शन के लिए नहीं बनाई गई है। आप सही हैं, हालांकि, अंतर्निहित आयाम-चयन विकल्पों का उपयोग करते हुए - जब वे उपलब्ध होते हैं - लगभग हमेशा लूप की तुलना में तेज होता है या कोशिकाओं में परिवर्तित होता है।
cjh

यह सच है, हालांकि, ऊपर दिए गए जवाब ने मुझे मैटलैब डॉक्यूमेंटेशन में वापस भेज दिया, क्योंकि मुझे उस सभी फैंटेसी की जरूरत नहीं थी, इसलिए मैं सरल समाधान की आवश्यकता में दूसरों को साझा करना और सहेजना चाहता था, खोज से।
13

-2

अगर आपको अपनी पंक्तियों की लंबाई पता है तो आप कुछ इस तरह से बना सकते हैं:

a=rand(9,3);
b=rand(9,3); 
arrayfun(@(x1,x2,y1,y2,z1,z2) line([x1,x2],[y1,y2],[z1,z2]) , a(:,1),b(:,1),a(:,2),b(:,2),a(:,3),b(:,3) )

2
इस उत्तर को देखने वाले किसी भी व्यक्ति के लिए: यह ऐसा करने का तरीका नहीं है! यह MATLAB में कुछ भी करने का तरीका नहीं है!
स्टीवी ग्रिफ़िन
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.