Możesz zastosować funkcję do każdego elementu w wektorze, mówiąc na przykład v + 1
, lub możesz użyć funkcji arrayfun
. Jak mogę to zrobić dla każdego wiersza / kolumny macierzy bez używania pętli for?
źródło
Możesz zastosować funkcję do każdego elementu w wektorze, mówiąc na przykład v + 1
, lub możesz użyć funkcji arrayfun
. Jak mogę to zrobić dla każdego wiersza / kolumny macierzy bez używania pętli for?
Wiele wbudowanych operacji, takich jak sum
i prod
jest już w stanie działać w wierszach lub kolumnach, więc możesz być w stanie refaktoryzować funkcję, którą stosujesz, aby to wykorzystać.
Jeśli nie jest to wykonalna opcja, jednym ze sposobów jest zebranie wierszy lub kolumn do komórek za pomocą mat2cell
lub num2cell
, a następnie użycie cellfun
operacji na wynikowej tablicy komórek.
Jako przykład, powiedzmy, że chcesz zsumować kolumny macierzy M
. Możesz to zrobić po prostu za pomocą sum
:
M = magic(10); %# A 10-by-10 matrix
columnSums = sum(M, 1); %# A 1-by-10 vector of sums for each column
A oto, jak byś to zrobił, używając bardziej skomplikowanej opcji 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
true = false
jest ważne stwierdzenie, jestem pewien, że jest to sposób w jaki można to zrobić (:sum(M, 1)
. Początkujący mogą pomyśleć, żesum
można go użyć w ten sposób do macierzy o dowolnej wielkości, a potem wpadną w zakłopotanie, gdy macierz pewnego dnia jest1-by-n
.Możesz potrzebować bardziej niejasnej funkcji Matlab bsxfun . Z dokumentacji Matlaba, bsxfun „stosuje operację binarną element po elemencie określoną przez funkcję uchwyt fun do tablic A i B, z włączoną ekspansją pojedynczych elementów”.
@gnovice stwierdził powyżej, że suma i inne podstawowe funkcje już działają na pierwszym nie-pojedynczym wymiarze (tj. wiersze, jeśli jest więcej niż jeden wiersz, kolumny, jeśli jest tylko jeden wiersz, lub wyższe wymiary, jeśli wszystkie niższe wymiary mają rozmiar == 1 ). Jednak bsxfun działa dla każdej funkcji, w tym (a zwłaszcza) funkcji zdefiniowanych przez użytkownika.
Na przykład, powiedzmy, że masz macierz A i wektor wierszowy BEg, powiedzmy:
Potrzebujesz funkcji power_by_col, która zwraca w wektorze C wszystkie elementy w A do potęgi odpowiedniej kolumny B.
Z powyższego przykładu C to macierz 3x3:
to znaczy,
Możesz to zrobić brutalną siłą używając repmat:
Lub możesz to zrobić w klasyczny sposób za pomocą bsxfun, który wewnętrznie zajmuje się krokiem repmat:
Więc bsxfun oszczędza ci kilku kroków (nie musisz jawnie obliczać wymiarów A). Jednak w niektórych moich nieformalnych testach okazuje się, że repmat jest mniej więcej dwa razy szybszy, jeśli funkcja, która ma zostać zastosowana (jak moja funkcja potęgowa, powyżej) jest prosta. Musisz więc wybrać, czy chcesz prostoty, czy szybkości.
źródło
Nie mogę komentować, jak wydajne jest to, ale oto rozwiązanie:
źródło
Opierając się na odpowiedzi Alexa , oto bardziej ogólna funkcja:
Oto porównanie między tymi dwiema funkcjami:
źródło
Dla kompletności / zainteresowania chciałbym dodać, że Matlab ma funkcję, która pozwala operować na danych na wiersz, a nie na element. Nazywa się
rowfun
( http://www.mathworks.se/help/matlab/ref/rowfun.html ), ale jedynym „problemem” jest to, że działa na tabelach ( http://www.mathworks.se/help/ matlab / ref / table.html ) zamiast macierzy .źródło
Dodając do ewoluującego charakteru odpowiedzi na to pytanie, począwszy od r2016b, MATLAB niejawnie rozszerzy pojedyncze wymiary, eliminując potrzebę
bsxfun
w wielu przypadkach.Z informacji o wersji r2016b :
źródło
Żadna z powyższych odpowiedzi nie zadziałała dla mnie „po wyjęciu z pudełka”, jednak następująca funkcja, uzyskana poprzez skopiowanie pomysłów z innych odpowiedzi, działa:
Pobiera funkcję
f
i stosuje ją do każdej kolumny macierzyM
.Na przykład:
źródło
Dzięki najnowszym wersjom Matlab możesz wykorzystać strukturę danych tabeli na swoją korzyść. Jest nawet operacja typu `` rowfun '', ale okazało się, że łatwiej jest to zrobić:
lub tutaj jest starszy, który miałem, który nie wymaga tabel, dla starszych wersji Matlab.
źródło
Zaakceptowaną odpowiedzią wydaje się być najpierw konwersja na komórki, a następnie użycie
cellfun
do operacji na wszystkich komórkach. Nie znam konkretnej aplikacji, ale generalnie myślę, że użyciebsxfun
do operowania na matrycy byłoby bardziej wydajne. Zasadniczobsxfun
stosuje operację element po elemencie w dwóch tablicach. Więc jeśli chcesz pomnożyć każdy element wn x 1
wektorze przez każdy element wm x 1
wektorze, aby uzyskaćn x m
tablicę, możesz użyć:To da ci macierz o nazwie, w
result
której pozycja (i, j) będzie i-tym elementemvec1
pomnożonej przez j-ty element funkcjivec2
.Możesz używać
bsxfun
do wszelkiego rodzaju wbudowanych funkcji i możesz zadeklarować własne. Dokumentacja zawiera listę wielu wbudowanych funkcji, ale w zasadzie możesz nazwać dowolną funkcję, która przyjmuje dwie tablice (wektor lub macierz) jako argumenty i uruchomić ją.źródło
Natknąłem się na to pytanie / odpowiedź, szukając sposobu obliczenia sum wierszy macierzy.
Chciałbym tylko dodać, że funkcja SUMA Matlaba faktycznie obsługuje sumowanie dla danego wymiaru, czyli standardowej macierzy z dwoma wymiarami.
Aby obliczyć sumy kolumn, wykonaj:
a dla sum wierszy po prostu zrób
Założę się, że jest to szybsze niż programowanie pętli for i konwersja do komórek :)
Wszystko to można znaleźć w pomocy Matlab dla programu SUM.
źródło
jeśli znasz długość swoich rzędów, możesz zrobić coś takiego:
źródło