Quelle est la meilleure façon pour itérer sur les colonnes d'une matrice?
Je veux appliquer une fonction à toutes les colonnes d'une matrice avec MATLAB. Par exemple, j'aimerais être en mesure d'appeler lisse sur chaque colonne d'une matrice, au lieu d'avoir lisse traiter de la matrice comme un vecteur (qui est le comportement par défaut si vous appelez smooth(matrix)
).
Je suis sûre qu'il doit être un plus idiomatiques façon de le faire, mais je ne le trouve pas, j'ai donc défini un map_column
fonction:
function result = map_column(m, func)
result = m;
for col = 1:size(m,2)
result(:,col) = func(m(:,col));
end
end
qui je peux appeler avec:
smoothed = map_column(input, @(c) (smooth(c, 9)));
Il n'y a rien de mal avec ce code? Comment pourrais-je l'améliorer?
OriginalL'auteur |
Vous devez vous connecter pour publier un commentaire.
Votre solution est parfaite.
Noter que horizcat exige une pénalité de performances pour les grandes matrices. Elle rend le code O(N^2) au lieu de O(N). Pour un 100x10,000 matrice, votre œuvre 2.6 s sur ma machine, le horizcat on prend de 64,5 s. Pour un 100x5000 de la matrice, la horizcat en œuvre de 15,7 s.
Si vous le vouliez, vous pourriez généraliser votre fonction un peu et faire de la il être en mesure d'effectuer une itération sur la dimension finale ou même arbitraire dimensions (et pas seulement les colonnes).
OriginalL'auteur Mr Fooz
L'MATLAB "pour" instruction passe en boucle sur les colonnes de ce qui est fourni - normalement, c'est juste les résultats dans une séquence de scalaires depuis le vecteur passé en pour (comme dans votre exemple ci-dessus) est un vecteur ligne. Cela signifie que vous pouvez réécrire le code ci-dessus comme ceci:
Si func ne renvoie pas un vecteur colonne, puis vous pouvez ajouter quelque chose comme
de force dans une colonne.
result
de la matrice, ce code ne fonctionne pas. Au lieu de cela, il pousse la matrice à chaque itération, ce qui entraîne un grand peine. Il faut toujours essayer de pré-allouer les tableaux dans MATLAB.OriginalL'auteur Tim Whitcomb
Peut-être vous pouvez toujours transformer la matrice de l'opérateur, et de transformer le résultat en retour.
Qu'au moins travaille avec la fft fonction.
'
est le complexe conjugué de transposer. Si l'objectif est de permuter les deux dimensions de la matrice, utilisation.'
.OriginalL'auteur Hallgrim
Un moyen de provoquer une boucle implicite à travers les colonnes d'une matrice est d'utiliser cellfun. Qui est, vous devez d'abord convertir la matrice d'une matrice de cellules, chaque cellule tiendra une colonne. Appelez ensuite cellfun. Par exemple:
Voir qu'ici j'ai calculé l'écart-type pour chaque colonne.
Bien sûr, de nombreuses fonctions de MATLAB sont déjà mis en place pour travailler sur des lignes ou des colonnes d'un tableau que l'utilisateur indique. C'est vrai pour les mst, bien sûr, mais c'est un moyen pratique pour vérifier que
cellfun
travaillé avec succès.'UniformOutput',false
à lacellfun
appel, puis concaténer tous (je l'espère) les vecteurs colonnes qui sont produites en arrière dans une matrice à l'aide dehorzcat(result{:})
ou, de manière équivalentecat(2,result{:})
. Cette solution est environ tout aussi efficace que le code de l'OP,cellfun
est mis en œuvre à l'aide d'une boucle dans une manière très similaire.OriginalL'auteur
N'oubliez pas de préallouer la matrice de résultats si vous travaillez avec des matrices de grande taille. Sinon pour ton CPU va passer beaucoup de cycles à plusieurs reprises ré-allocation de la matrice à chaque fois qu'il ajoute une nouvelle ligne/colonne.
OriginalL'auteur Jason S
Si c'est l'un des cas d'utilisation pour votre fonction, il serait peut-être une bonne idée pour faire la fonction de parcourir les colonnes automatiquement si l'entrée n'est pas un vecteur.
Ce n'est pas exactement résoudre votre problème, mais elle permettrait de simplifier les fonctions d'utilisation. Dans ce cas, la sortie doit être une matrice, trop.
Vous pouvez également transformer la matrice à une longue colonne en utilisant
m(:,:) = m(:)
. Toutefois, cela dépend de votre fonction si cela avait un sens.OriginalL'auteur bastibe