IdentifiantMot de passe
Loading...
Mot de passe oublié ?Je m'inscris ! (gratuit)
Navigation

Inscrivez-vous gratuitement
pour pouvoir participer, suivre les réponses en temps réel, voter pour les messages, poser vos propres questions et recevoir la newsletter

Python Discussion :

la type de retour d'une fonction constante dépend d'un détail purement syntaxique


Sujet :

Python

Vue hybride

Message précédent Message précédent   Message suivant Message suivant
  1. #1
    Membre averti
    Homme Profil pro
    Étudiant
    Inscrit en
    Février 2019
    Messages
    17
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 30
    Localisation : Pays-Bas

    Informations professionnelles :
    Activité : Étudiant

    Informations forums :
    Inscription : Février 2019
    Messages : 17
    Par défaut la type de retour d'une fonction constante dépend d'un détail purement syntaxique
    Bonjour,

    Il se passe quelque chose d'étrange quand j'applique une fonction constante à un Numpy array. Voyez plutôt:

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
     
    import numpy as np
     
    def zero(x):
        """une fonction qui renvoie toujours 0."""
        return 0
     
    def encoreZero(x):
        """la fonction d'avant + un tour de passe-passe apparamment inutile."""
        return x - x
     
    myArray = np.linspace(0, 3, 3)  # un Array [0, 0, 0] 
    print(zero(myArray))            # affiche 0 à l'écran.
    print(encoreZero(myArray))      # affiche [0, 0, 0] à l'écran.
    Du coup quand je veux faire un tracé de la fonction zero ça me renvoie l'erreur:
    ValueError: x and y must have same first dimension, but have shapes (100,) and (1,)
    alors qu'avec x-x au lieu de 0 tout va bien. (Vous comprenez ce que je veux dire? Je peux ajouter un le bout de code donnant cette erreur-là s'il le faut.)

    Bref, j'aimerais qu'une fonction qui reçoit en paramètre un Numpy Array soit appliquée à chacun des éléments du Array, quelle que soit la valeur de retour et la syntaxe utilisée pour la définir la fonction. Vous pouvez me donner votre conseil à ce sujet? Merci d'avance.

  2. #2
    Membre Expert
    Avatar de Pyramidev
    Homme Profil pro
    Tech Lead
    Inscrit en
    Avril 2016
    Messages
    1 513
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Haute Garonne (Midi Pyrénées)

    Informations professionnelles :
    Activité : Tech Lead

    Informations forums :
    Inscription : Avril 2016
    Messages : 1 513
    Par défaut
    Bonjour,

    C'est normal.

    Soit my_array un tableau numpy à une dimension et f une fonction.
    Pour retourner un tableau numpy à une dimension des résultats de f sur chaque élément du tableau de départ, on peut faire : np.asarray([f(x) for x in my_array]).
    Il peut exister des cas où f(my_array) retourne le même résultat, mais ce n'est pas vrai pour toutes les fonctions f. Il faut comprendre comment ça marche sous le capot.

    Exemple :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    import numpy as np
     
    my_array = np.array([4, 5])
     
    def f(x):
        print(f"x: {x}")
        ten_x = 10*x
        print(f"ten_x: {ten_x}")
        f_result = ten_x + 2
        print(f"f_result: {f_result}")
        return f_result
     
    print("f(my_array):")
    result = f(my_array)
    print(result)
    print()
    print("np.asarray([f(x) for x in my_array]):")
    result = np.asarray([f(x) for x in my_array])
    print(result)
    Résultat :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    f(my_array):
    x: [4 5]
    ten_x: [40 50]
    f_result: [42 52]
    [42 52]
     
    np.asarray([f(x) for x in my_array]):
    x: 4
    ten_x: 40
    f_result: 42
    x: 5
    ten_x: 50
    f_result: 52
    [42 52]
    Dans le résultat, tu peux constater que les deux opérations retournent le même tableau, mais avec une logique d'exécution différente.

  3. #3
    Membre averti
    Homme Profil pro
    Étudiant
    Inscrit en
    Février 2019
    Messages
    17
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 30
    Localisation : Pays-Bas

    Informations professionnelles :
    Activité : Étudiant

    Informations forums :
    Inscription : Février 2019
    Messages : 17
    Par défaut
    Merci pour la réponse. Je sais quoi faire maintenant.

    Il peut exister des cas où f(my_array) retourne le même résultat, mais ce n'est pas vrai pour toutes les fonctions f. Il faut comprendre comment ça marche sous le capot.
    Justement, je ne comprends pas. J'ai encore cherché un peu avec Google, et j'ai pu trouver plein de sources suggérant des façons d'appliquer une fonction par élément. Seulement je n'ai pas trouvé d'avertissement ou d'éclaircissement quand aux expressions du style fonctionSimple(tableau). Mais bon tant pis, maintenant j'ai quelque chose qui marche bien.

    Encore une fois merci, et bonne fin d'année.

  4. #4
    Membre Expert
    Avatar de Pyramidev
    Homme Profil pro
    Tech Lead
    Inscrit en
    Avril 2016
    Messages
    1 513
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Haute Garonne (Midi Pyrénées)

    Informations professionnelles :
    Activité : Tech Lead

    Informations forums :
    Inscription : Avril 2016
    Messages : 1 513
    Par défaut
    Citation Envoyé par Bram van Dam Voir le message
    Justement, je ne comprends pas.
    Quand j'écris f(my_array) avec my_array un tableau numpy à une dimension, f n'est pas appelée autant de fois qu'il y a d'éléments. Elle n'est appelée qu'une seule fois, avec en argument my_array.
    Le code :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
     
    def f(x):
        print(f"x: {x}")
        ten_x = 10*x
        print(f"ten_x: {ten_x}")
        f_result = ten_x + 2
        print(f"f_result: {f_result}")
        return f_result
     
    result = f(my_array)
    équivaut à :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
     
    x = my_array
    print(f"x: {x}")
    ten_x = 10*x
    print(f"ten_x: {ten_x}")
    f_result = ten_x + 2
    print(f"f_result: {f_result}")
    result = f_result
    mis à part que les variables définies dans la fonction (x, ten_x et f_result) ne sont visibles et accessibles qu'à l'intérieur de la fonction.

    Cependant, dans le code ci-dessus, quand x est un tableau numpy, 10*x fait bien une multiplication par 10 élément par élément, car c'est comme ça que la multiplication a été définie pour un tableau numpy.
    De même, quand ten_x est un tableau numpy, ten_x + 2 ajoute bien 2 élément par élément, car c'est comme ça que l'addition a été définie pour un tableau numpy.
    C'est pour ça que, dans ce cas particulier, f(my_array) retourne la même chose que np.asarray([f(x) for x in my_array]). Tu peux voir ça dans ce qu'affiche mes appels à print.

    Quand tu écris :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
     
    def zero(x):
        """une fonction qui renvoie toujours 0."""
        return 0
    ta fonction retourne 0 quel que soit ce que tu lui passes en argument, même un tableau numpy.

    Par contre, quand tu écris :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
     
    def encoreZero(x):
        """la fonction d'avant + un tour de passe-passe apparemment inutile."""
        return x - x
    si x est un tableau numpy, alors x - x fait une soustraction élément par élément, car c'est comme ça que la soustraction a été définie pour un tableau numpy. Ce n'est pas la fonction encoreZero qui est appelée élément par élément, mais la soustraction qu'elle contient.

  5. #5
    Expert éminent
    Homme Profil pro
    Architecte technique retraité
    Inscrit en
    Juin 2008
    Messages
    21 743
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Manche (Basse Normandie)

    Informations professionnelles :
    Activité : Architecte technique retraité
    Secteur : Industrie

    Informations forums :
    Inscription : Juin 2008
    Messages : 21 743
    Par défaut
    Salut,

    Citation Envoyé par Bram van Dam Voir le message
    Bref, j'aimerais qu'une fonction qui reçoit en paramètre un Numpy Array soit appliquée à chacun des éléments du Array, quelle que soit la valeur de retour et la syntaxe utilisée pour la définir la fonction. Vous pouvez me donner votre conseil à ce sujet? Merci d'avance.
    Une fonction reste une fonction: elle sait traiter les arguments qu'on lui passe pourvu qu'ils soient du type attendu et retournera un objet d'un type prédéterminé, histoire que l'appelant de la fonction sache quoi faire du résultat.

    note: le programmeur écrit la fonction qui... et si elle ne le fait pas, c'est pas un problème de syntaxe!

    Pour ce qui est d'appliquer une fonction aux différents items d'un tableau numpy, vous avez différentes méthodes et cet article de SOW en fait le tour.

    - W
    Architectures post-modernes.
    Python sur DVP c'est aussi des FAQs, des cours et tutoriels

+ Répondre à la discussion
Cette discussion est résolue.

Discussions similaires

  1. Réponses: 5
    Dernier message: 27/08/2015, 19h52
  2. Type de retour d'une fonction PL/PGSQL
    Par the java lover dans le forum PostgreSQL
    Réponses: 3
    Dernier message: 21/01/2009, 11h13
  3. [PL/SQL] type de retour d'une fonction
    Par foffffa dans le forum SQL
    Réponses: 4
    Dernier message: 27/03/2008, 15h06
  4. Réponses: 5
    Dernier message: 29/09/2006, 17h17
  5. [Oracle 9.1] Types de retour d'une fonction PL/SQL
    Par ftrifiro dans le forum PL/SQL
    Réponses: 8
    Dernier message: 12/10/2005, 16h54

Partager

Partager
  • Envoyer la discussion sur Viadeo
  • Envoyer la discussion sur Twitter
  • Envoyer la discussion sur Google
  • Envoyer la discussion sur Facebook
  • Envoyer la discussion sur Digg
  • Envoyer la discussion sur Delicious
  • Envoyer la discussion sur MySpace
  • Envoyer la discussion sur Yahoo