J'essaie de trouver un moyen le plus rapide de trouver des valeurs uniques dans une matrice et de supprimer À l'heure actuelle, j'ai deux solutions: P > donc dans ce cas, Je voulais faire du temps les différentes solutions. P> 0 code> comme une possibilité de valeur unique. dataarray code> est équivalent à: p> résultat1 code> est égal à [1; 2] code> et résultat2 code> est égal à [0; 1; 2] code>.
La fonction code> unique > est plus rapide mais je ne veux pas 0 code> à envisager. Existe-t-il un moyen de le faire avec unique code> et ne pas envisager 0 code> comme valeur unique? Y a-t-il une autre alternative? P> Elapsed time is 5.153571 seconds. % FCT1 Initial
Elapsed time is 3.837637 seconds. % FCT2 My solution
Elapsed time is 3.464652 seconds. % FCT3 Pursuit solution
Elapsed time is 3.414338 seconds. % FCT32 Pursuit solution with chappjc comment
Elapsed time is 4.097164 seconds. % FCT4 chappjc solution
Elapsed time is 0.936623 seconds. % FCT5 chappjc 2nd solution
4 Réponses :
Pourquoi ne pas retirer les zéros comme une deuxième étape:
résultat2 = résultat2 (résultat2 ~ = 0) code> peut être plus rapide: Stackoverflow.com/questions/12421345/...
Voici une suggestion farfelée avec grâce à Luis Mendo pour souligner que avec Notez que cette solution nécessite des données valorisées (pas nécessairement un type de données entier, mais juste pas avec des composants décimaux). La comparaison des valeurs de points flottants pour l'égalité, comme le ferait des valeurs code> uniques, est périlleux. Voir ici et ICI . P> Suggestion originale: Combinez ou supprimez avec indexation logique après Je préfère généralement ne pas attribuer Suppression de zéros après accumarray code>, démontré à l'aide de données de test de floris: nonzeros code>, il n'est pas nécessaire d'exécuter résultat = résultat (résultat> 0) code>! p>
unique code> avec SetDiff code>: p> unique code>: p> [] code> comme dans ( résultat (résultat == 0) = []; code>) car il devient très inefficace pour les grands ensembles de données. P > Unique code> devrait être plus rapide car celui-ci fonctionne moins de données (sauf si chaque élément est unique, ou si a code> dataarray code> > est très court). p> p>
Lorsque vous utilisez A code> 10000x10, j'obtiens l'erreur suivante: ??? Erreur lors de l'utilisation de ==> Accumparray Taille variable maximale autorisée par le programme est dépassée.
@M_Power doit utiliser uniquement la première colonne ( A (:, 1) code>) comme les autres solutions. Mis à jour.
Wacky, peut-être. Mais rapide!
Et s'il existe double code> dans le tableau code> code>? Je reçois l'erreur Les premiers sous-traitants doivent contenir des sous-domestibles entier positif. Code>.
@M_Power Droite, cela et le Sans Solutions CODE> ne fonctionnent que pour des données valorisées entier, mais vous ne souhaitez généralement pas comparer les valeurs de point flottantes pour l'égalité (comme avec unique code> aussi ). Je devrais dire que vous vraiment i> ne devrait pas.
@chappjc Le fait est qu'il existe double code> dans mon tableau, je n'ai pas pensé que cela causerait un problème dans mon exemple initial.
@M_Power je reconsidérerais le problème en fonction des valeurs attendues. Sont-ils continus ou seront-ils certaines valeurs? Il y a Problèmes utilisant un unique sur le double bien que cela vous permettrait de l'exécuter . Il faut se méfier.
@chappjc +1, mais pourquoi ne pas supprimer les éléments zéro avant i> accumarray code> ?: résultat = Rechercher (ACCUMARRAY (NONZEROS (A (:: 1)) + 1 , 1) -1); code>. Il faut moins de temps sur mon ordinateur.
J'ai aussi trouvé une autre façon de le faire:
result2 = unique(dataArray(dataArray(:,1)>0,1));
Juste un conseil: 1: fin code> est identique à celui de : code>. Mais oui, c'est une solution réalisable.
Strictement parler que vous devriez utiliser dataarray (:, 1) ~ = 0 code> pour permettre la possibilité de nombres négatifs. Je soupçonne que c'est plus rapide de retirer le zéro supplémentaire à la fin (réseau plus petit pour manipuler).
Juste pour ajouter à la clameur générale - voici trois méthodes différentes. Ils donnent tous la même réponse, mais des horaires légèrement différents: sur ma machine, les horaires (pour une matrice de 100 000 éléments) étaient les suivants: P> a = round(a * 1000);
mina = min(a(:));
b = find(accumarray(a - mina + 1, 1)) + mina - 1;
b = 0.001 * b(b ~= 0);
Je préfère accumarray code> à SPARSE code>. Tu veux ajouter les horaires. ;)
@chappjc c'était une suggestion formidable. Il est 3 fois plus rapide (sur ma machine)!
Votre troisième solution fonctionne correctement, mais je ne peux pas l'utiliser pour ce que je fais. J'ai besoin d'avoir les mêmes valeurs exactes, pas des valeurs arrondies.
@M_Power Pourriez-vous publier des données réelles sur Dropbox ou quelque part similaire. Je suis sceptique que vous obtiendrez une solution satisfaisante avec tout ce qui n'utilise pas de tolérances, y compris unique code>. Tester des valeurs de points flottants pour l'égalité fonctionne rarement comme souhaité.
@Floris Comme je viens de commenter la réponse de Chappjc: pourquoi ne pas supprimer les éléments zéro initialement i>? Dans la version code> Accumarray CODE>, qui semble sauvegarder un peu de temps (sur ma machine): b5 = trouver (Accumarray (nonzeros (A (:, 1)) + 1,1) -1 ) code>
@CHAPPJC Vous avez raison, le
'lignes' code> n'est pas nécessaire. Je l'ai supprimé.Vous voudrez peut-être essayer les horaires plus longs
dataarray code> plutôt que plus d'itérations. Mais juste pour des coups de pied, lancez-le dansfct3 = fct3 (fct3 ~ = 0); code> car cela est généralement plus rapide que d'attribuer[] code>;D'accord avec @CHAPPJC - Votre timing est dominé par une ou deux appels de fonction. Essayez ceci sur un "gros" tableau (voir ma réponse pour un exemple). Vous avez surtout chronométrant la surcharge de boucle (et d'appel de fonction) avec votre code actuel, plutôt que de l'efficacité des fonctions une fois que vous êtes à l'intérieur d'eux.
@chappjc 2nd Solution semble être le plus rapide, pour l'instant: ré.
@M_Power examine les réponses de Floris, ainsi que ses commandes de données de test qui retirent certains éléments pour un test plus robuste. Si vous le souhaitez, vous pouvez également faire toutes les 10 colonnes d'un coup avec
rand (10E3,10) code>.@chappjc j'ai fait les modifications. Il n'y a pas de modification des résultats finaux.
@m_Power comme je l'ai mentionné dans mes commentaires ci-dessous, il y a des défis avec des numéros de points flottants même avec
unique code>. Voir ici et ici . Considérez si vous pouvez utiliser avec des index valorisés intégrés plutôt que sur des valeurs de points flottantes.@chappjc Inspiré par votre dernier commentaire J'ai mis à jour ma réponse une fois de plus ...