7
votes

Créez une matrice d'un vecteur où chaque ligne est une version décalée du vecteur

J'ai un tableau numpy comme celui-ci xxx

et je souhaite créer un tableau qui ressemble à ceci: xxx

Ainsi, Chaque ligne correspond à ar qui est décalée par l'index de la ligne + 1.

Une implémentation simple pourrait ressembler à ceci: xxx < p> Qui me donne la sortie souhaitée.

Ma question est de savoir s'il existe une façon plus intelligente de faire cela qui évite la boucle.


0 commentaires

3 Réponses :


4
votes

Voici une approche xxx

dans votre cas, nous construisons tampon pour être xxx

puis aplatir puis aplatiré Il, la coupe, remodelez-le pour obtenir roulé : xxx

et enfin, découpez la poubelle Dernières colonnes


0 commentaires

5
votes

Voici une approche en utilisant Progrès numpy essentiellement rembourrage avec les éléments de restover, puis les nous aidant à créer une version décalée assez efficace - xxx

échantillons d'échantillons - xxx

test d'exécution - xxx

Fabriquer une copie (si vous souhaitez apporter des modifications et non seulement utiliser comme tableau unique) gagné 't nous fait trop mal pour les progrès méthode - xxx


14 commentaires

Cela utilise moins de mémoire que ma solution, mais la sortie n'est pas écrite en toute sécurité. Je doute que c'est une question cependant, en faisant cette meilleure solution


@ Scientifique: qu'entendez-vous par "pas en toute sécurité écrite"?


@Cleb: Je veux dire que si vous essayez de changer l'un des 4 s dans le tableau, tous changeront à la fois!


@ERIC: OK, la création d'une copie devrait alors éviter ce problème, je suppose?


@Cleb Yup, devrait être bien alors.


Merci pour les timings!


Il s'avère que les documents numpus en ligne n'incluent pas réellement la documentation de as_strided - j'ai soumis Un patch pour permettre la construction de cette page


@Eric Yup, la partie de la documentation nécessite un travail sûr. Nous utilisons ces documents scipes pour cela jusqu'à présent. Merci pour la soumission!


@Divakar: Pouvez-vous ajouter scipy.linalg.circirculant à votre référence?


@ Certièrement sûr! Ajoutée.


Je soupçonne as_strided est laissé quelque peu caché car il s'agit d'une fonction "dangereuse". Une erreur dans les arguments peut conduire à l'interprète Python Crashing (Segfault, violations d'accès à la mémoire et tout cela).


Bonjour Divakar, Soins de Revenit Votre PR à Scipy ?


@Percusse ah oui! Eu ça à l'esprit. Continuez à perdre cependant. Je reviendrais bientôt, espérons-le en quelques jours. Merci pour le rappel!


@Divakar: Heureux de voir que cela a été incorporé maintenant, merci pour vos efforts!



4
votes

Les deux réponses existantes vont bien; Cette réponse n'est probablement que d'intérêt que si vous utilisez déjà Scipy.

La matrice que vous décrivez est connue sous le nom de matrice circulante . Si cela ne vous dérange pas de la dépendance sur Scipy, vous pouvez utiliser scipy.linalg.circirculant pour créer un: xxx


11 commentaires

J'utilise Scipy, de sorte que la réponse est très utile, car elle est aussi la plus lisible (upvoted). En termes de vitesse, il semble moins efficace, mais bien qu'il y a déjà un intégré à celui-ci!


On dirait que Scipey vaut un patch d'utiliser la mise en œuvre plus rapide de @ Divakar. Vous pouvez voir la mise en œuvre scipe ici < / a>


@ Arérique bonne idée! Scipey pourrait utiliser des tours de progrès à coup sûr!


Une fonction avec une meilleure performance serait géniale. Je ne suis pas sûr de renvoyer un tableau avec des progrès funky. Ce serait un changement incompatible à l'envers - nous n'avons aucune idée de la manière dont les gens utilisent le résultat de circulant . Quoi qu'il en soit, des discussions supplémentaires devraient être terminées dans une question sciée sur GitHub, ou dans la liste de diffusion SciPy-Dev.


@Warrenweckesser: retourner funky_strides.copy () est toujours une vitesse de 10x sur cette petite donnée et serait invisible à l'utilisateur


"... serait invisible à l'utilisateur" oui, jusqu'à ce qu'ils commencent à modifier la matrice en place. Ensuite, au moins pour l'utilisateur sans méfiance, le plaisir commence.


Essayer de forcer la question à nouveau comme j'adorerais voir SciPy Utiliser certains avantage . Pourriez-vous expliquer sur la partie "Fun Début"? Comme @ eric a souligné avec une copie, cela devrait être correct car la sortie aurait son propre espace mémoire séparé de la matrice d'entrée. J'espère que je ne manque pas quelque chose ici.


Et je voulais dire si nous faisons la copie dans la fonction circulant . Je devine que je devrais être correct alors.


Hmmm ... Si une copie avec des progrès "réguliers" est retournée, je ne me souviens pas de ce que j'étais inquiet. Et s'il y a encore un grand gain de performance, cela ressemble à un changement intéressant.


@Warrenweckesser génial! Alors, comment devrais-je continuer dessus? Devrais-je enregistrer un problème sur github.com/scipy/scipy/issues avec des balises: Amélioration , etc., etc. Liaison à cela, donc poster? On dirait que vous êtes un contributeur sur Scipy, il serait donc agréable d'obtenir des conseils.


@Divakar: créer un nouveau problème avec une description de l'amélioration serait un bon départ. Créer une demande de traction que implémente l'amélioration serait encore meilleure! Voir Github.com/scipy/scipy/scipy/blob/master/hacking.rst .txt pour des informations sur la contribution à Scipy.