MATLAB में मानचित्र कार्य?


100

मैं थोड़ा हैरान हूं कि MATLAB में मैप फ़ंक्शन नहीं है, इसलिए मैंने खुद को एक साथ हैक किया क्योंकि यह ऐसा कुछ है जिसके बिना मैं नहीं रह सकता। वहाँ एक बेहतर संस्करण है? क्या MATLAB के लिए कुछ मानक कार्यात्मक प्रोग्रामिंग लाइब्रेरी है जो मुझे याद आ रही है?

function results = map(f,list)
% why doesn't MATLAB have a Map function?
results = zeros(1,length(list));
for k = 1:length(list)
    results(1,k) = f(list(k));
end

end

उपयोग उदाहरण के लिए होगा

map( @(x)x^2,1:10)

12
सबक # 1 अन्य भाषाओं से मतलाब में जा रहा है: छोरों के लिए उपयोग न करें, वे एक वेक्टर समाधान की तुलना में परिमाण धीमी के कुछ आदेश हैं।
कूकीऑफफोर्ट्यून

15
जेआईटी की शुरुआत के साथ, लूप के लिए जुर्माना नहीं लगता है जो उन्होंने एक बार किया था।
MatlabDoug

@CookieOfFortune मुझे लगता है कि यह अब सच नहीं है ...
एंडर बिगुरी

2
@AnderBiguri मुझे लगता है कि उन्होंने कुछ सुधार किए हैं लेकिन यह अभी भी बहुत धीमा है।
CookieOfFortune

कार्यात्मक लाइब्रेरी फ़ाइल एक्सचेंज में है map, foldl(भी रूप में जाना जाता reduce), select(उर्फ filter), और अन्य अपरिहार्य उपहार। अनुशंसित (यदि आपको मैटलैब का उपयोग करना है)।
अहमद फ़सीह

जवाबों:


133

संक्षिप्त उत्तर: बिल्ट-इन फ़ंक्शन arrayfunवैसा ही करता है जैसा आपका mapफ़ंक्शन सांख्यिक सरणियों के लिए करता है:

>> y = arrayfun(@(x) x^2, 1:10)
y =

     1     4     9    16    25    36    49    64    81   100

दो अन्य अंतर्निहित कार्य हैं जो समान व्यवहार करते हैं: cellfun(जो सेल सरणियों के तत्वों पर संचालित होता है) औरstructfun (जो एक संरचना के प्रत्येक क्षेत्र पर संचालित होता है)।

हालांकि, ये कार्य अक्सर आवश्यक नहीं होते हैं यदि आप वेक्टराइजेशन का लाभ उठाते हैं, विशेष रूप से तत्व-वार अंकगणितीय ऑपरेटरों का उपयोग करते हुए । आपके द्वारा दिए गए उदाहरण के लिए, एक वेक्टरकृत समाधान होगा:

>> x = 1:10;
>> y = x.^2
y =

     1     4     9    16    25    36    49    64    81   100

कुछ ऑपरेशन स्वचालित रूप से तत्वों के पार संचालित होंगे (जैसे कि वेक्टर के लिए एक स्केलर मान जोड़ना) जबकि अन्य ऑपरेटरों के पास तत्व-वार ऑपरेशन ( .ऑपरेटर से पहले द्वारा चिह्नित ) के लिए एक विशेष वाक्यविन्यास है । MATLAB में कई अंतर्निहित फ़ंक्शन तत्व-वार संचालन का उपयोग करके वेक्टर और मैट्रिक्स तर्कों पर काम करने के लिए डिज़ाइन किए गए हैं (अक्सर किसी दिए गए आयाम पर लागू होते हैं, जैसे sumऔरmean उदाहरण के लिए), और इस प्रकार मानचित्र कार्यों की आवश्यकता नहीं होती है।

संक्षेप में, प्रत्येक तत्व को एक ऐरे में वर्गाकार करने के कुछ अलग तरीके हैं:

x = 1:10;       % Sample array
f = @(x) x.^2;  % Anonymous function that squares each element of its input

% Option #1:
y = x.^2;  % Use the element-wise power operator

% Option #2:
y = f(x);  % Pass a vector to f

% Option #3:
y = arrayfun(f, x);  % Pass each element to f separately

बेशक, इस तरह के एक सरल ऑपरेशन के लिए, विकल्प # 1 सबसे समझदार (और कुशल) विकल्प है।


2
एक को ध्यान देना चाहिए कि विकल्प 1 न केवल सरल है, बल्कि तेज भी है (विकल्प 3 की तुलना में, 2 1 के समान होना चाहिए)!
डिडेरिक सी। नीहॉस्टर

10

वेक्टर और तत्व-वार संचालन के अलावा, cellfunसेल सरणियों पर मैपिंग फ़ंक्शन के लिए भी है । उदाहरण के लिए:

cellfun(@upper, {'a', 'b', 'c'}, 'UniformOutput',false)
ans = 
    'A'    'B'    'C'

यदि 'यूनिफ़ॉर्मऑउटपुट' सत्य है (या प्रदान नहीं किया गया है), तो यह सेल सरणी के आयामों के अनुसार परिणामों को संक्षिप्त करने का प्रयास करेगा, इसलिए

cellfun(@upper, {'a', 'b', 'c'})
ans =
ABC

2

मतलाब के वैश्वीकरण का उपयोग करते हुए एक सरल समाधान होगा:

a = [ 10 20 30 40 50 ]; % the array with the original values
b = [ 10 8 6 4 2 ]; % the mapping array
c = zeros( 1, 10 ); % your target array

अब, टाइपिंग

c( b ) = a

रिटर्न

c = 0    50     0    40     0    30     0    20     0    10

c (b) b द्वारा दिए गए सूचकांकों पर c के तत्वों के साथ आकार 5 के एक वेक्टर का संदर्भ है। अब यदि आप इस संदर्भ सदिश को मान देते हैं, तो c में मूल मान अधिलेखित हैं, क्योंकि c (b) में c और मान की कोई प्रतिलिपि नहीं है।


1

ऐसा लगता है कि निर्मित सरणीफ़न काम नहीं करता है अगर परिणाम की आवश्यकता फ़ंक्शन का एक सरणी है: उदाहरण के लिए: मानचित्र (@ (x) [xx ^ 2 x ^ 3], 1: 10)

नीचे दिए गए मामूली मोड इस काम को बेहतर बनाते हैं:

function results = map(f,list)
% why doesn't MATLAB have a Map function?
for k = 1:length(list)
    if (k==1)
        r1=f(list(k));
        results = zeros(length(r1),length(list));
        results(:,k)=r1;
    else
        results(:,k) = f(list(k));

    end;
end;
end

5
ARRAYFUN आपके उदाहरण के लिए काम करेगा, आपको ..., 'UniformOutput', false);अपने सरणियों वाले सेल सरणी आउटपुट बनाने के लिए बस इनपुट तर्कों को शामिल करना होगा , फिर एक गैर-सेल सरणी में इच्छित स्वरूपित करें और उन्हें संयोजित करें।
gnovice

0

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

दूसरे शब्दों में, यह


a = 1:10;
a.^2

इससे बहुत तेज है


a = 1:10;
map(@(x)x^2, a)

मानचित्र की अपनी परिभाषा मानते हुए।


2
मुझे लगता है कि उनकी बात यह नहीं थी कि वे इसे लूप करना चाहते थे, बल्कि इसके परिणाम के रूप में निर्दिष्ट किया जाना चाहिए क्योंकि आपूर्ति की गई फ़ंक्शन के परिणाम को सरणी के संबंधित तत्वों के अनुरूप तत्वों पर लागू किया जा सकता है। मैं ज्यादा मैटलैब नहीं जानता, लेकिन ऐसा लगता है कि अरफुन काम करता है।

1
अधिकांश अंतर्निहित मैटलैब फ़ंक्शंस और ऑपरेटर पहले से ही ऐसा करते हैं: वे इनपुट ऐरे के प्रत्येक तत्व पर काम करते हैं, और वे परिणाम के एक संबंधित सरणी को वापस करते हैं।
दीमा

0

आप की जरूरत नहीं है mapएक अदिश-समारोह है कि मानों की सूची को लागू किया जाता से प्रत्येक मान के लिए आवेदन किया है और इसलिए के लिए इसी तरह काम करता है के बाद से map। कोशिश करो

l = 1:10
f = @(x) x + 1

f(l)

अपने विशेष मामले में, आप भी लिख सकते हैं

l.^2

9
-1: यह वास्तव में सच नहीं है। मैटलैब में एक प्रकार की प्रणाली नहीं है जो स्केलर फ़ंक्शन को निर्दिष्ट करने के लिए पर्याप्त मजबूत है। f को वेक्टर के साथ कहा जाता है और एक एकल वेक्टर जोड़ आपके उदाहरण में किया जाता है। इसे सत्यापित करने के लिए, कोड को चलाने से पहले अपने कोड नमूने ("प्रोफ़ाइल पर", उसके बाद "प्रोफ़ाइल ऑफ़ रिपोर्ट") को प्रोफ़ाइल करें। आप देखेंगे कि f के लिए एक ही कॉल है।
श्री फ़ूज

-1

पिछले उत्तरों में वर्णित समाधान को वेक्टर करना, गति के लिए संभवतः सबसे अच्छा समाधान है। वेक्टरिंग भी बहुत मैटलैबी है और अच्छा लगता है।

इसके साथ ही मतलाब के पास अब एक मैप कंटेनर क्लास है।

Http://www.mathworks.com/help/matlab/map-containers.html देखें


Op उच्च-क्रम फ़ंक्शन के बारे में बात कर रहा है, अर्थात, cellfunएट अल।, हैश टेबल या की-वैल्यू जोड़े नहीं।
अहमद फ़सीह
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.