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 :

pandas series : trouver valeur non numérique [Python 3.X]


Sujet :

Python

  1. #1
    Membre confirmé
    Profil pro
    Inscrit en
    Octobre 2009
    Messages
    206
    Détails du profil
    Informations personnelles :
    Localisation : Belgique

    Informations forums :
    Inscription : Octobre 2009
    Messages : 206
    Par défaut pandas series : trouver valeur non numérique
    Bonjour,
    j'ai un objet series Pandas contenant d'abord des valeurs numériques puis une chaîne de caractère et encore des valeurs numériques.
    Je voudrais extraire de cette série la première partie numérique, soit:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    test = pd.Series([1, 2, 3, "date", 5, 6, 7])
    et obtenir finalement
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    test = pd.Series([1, 2, 3])
    ce, en repérant l'index de la valeur non numérique.
    Je bloque ! Pouvez vous m'orienter svp ?
    Merci

  2. #2
    Membre confirmé
    Profil pro
    Inscrit en
    Octobre 2009
    Messages
    206
    Détails du profil
    Informations personnelles :
    Localisation : Belgique

    Informations forums :
    Inscription : Octobre 2009
    Messages : 206
    Par défaut
    J'ai trouvé cette méthode mais il y a certainement plus élégant :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    idx = test[test =="date"].index[0]
    test = test[0:idx-1]

  3. #3
    Membre confirmé
    Profil pro
    Inscrit en
    Octobre 2009
    Messages
    206
    Détails du profil
    Informations personnelles :
    Localisation : Belgique

    Informations forums :
    Inscription : Octobre 2009
    Messages : 206
    Par défaut
    Puis ce ne sera pas toujours cette chaîne de caractère là. Il me faudrait un truc du genre isnumeric mais je ne sais si ça existe

  4. #4
    Membre prolifique
    Avatar de Sve@r
    Homme Profil pro
    Ingénieur développement logiciels
    Inscrit en
    Février 2006
    Messages
    12 840
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Oise (Picardie)

    Informations professionnelles :
    Activité : Ingénieur développement logiciels
    Secteur : Aéronautique - Marine - Espace - Armement

    Informations forums :
    Inscription : Février 2006
    Messages : 12 840
    Billets dans le blog
    1
    Par défaut
    Bonjour
    Citation Envoyé par cpalperou Voir le message
    Puis ce ne sera pas toujours cette chaîne de caractère là. Il me faudrait un truc du genre isnumeric mais je ne sais si ça existe
    Oui ça existe mais sur les strings. Exemple "5".isnumeric() renvoie vrai.
    Donc solution: transformer chaque valeur en string puis tester si la string est numérique: test = pd.Series(x for x in test if str(x).isnumeric()).
    Autre solution: garder les éléments "non strings": test = pd.Series(x for x in test if not isinstance(x, str)).
    Autre solution: garder les éléments int (et peut-être float s'il y en a): test = pd.Series(x for x in test if isinstance(x, (int, float))).

    Donc en effet il y a plus élégant.
    Mon Tutoriel sur la programmation «Python»
    Mon Tutoriel sur la programmation «Shell»
    Sinon il y en a pleins d'autres. N'oubliez pas non plus les différentes faq disponibles sur ce site
    Et on poste ses codes entre balises [code] et [/code]

  5. #5
    Membre confirmé
    Profil pro
    Inscrit en
    Octobre 2009
    Messages
    206
    Détails du profil
    Informations personnelles :
    Localisation : Belgique

    Informations forums :
    Inscription : Octobre 2009
    Messages : 206
    Par défaut
    Merci beaucoup pour vos propositions effectivement bien plus élégante.
    Toutefois, il me semble que vos solutions permettent de garder toutes les valeurs numériques et de supprimer les strings. Je souhaite en fait, garder uniquement la 1ère partie numérique.
    Dès qu'il y a un string : stop !
    Dans mon exemple du 1er test, je voudrais obtenir
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    test = pd.Series([1, 2, 3])
    .
    Encore merci

  6. #6
    Membre prolifique
    Avatar de Sve@r
    Homme Profil pro
    Ingénieur développement logiciels
    Inscrit en
    Février 2006
    Messages
    12 840
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Oise (Picardie)

    Informations professionnelles :
    Activité : Ingénieur développement logiciels
    Secteur : Aéronautique - Marine - Espace - Armement

    Informations forums :
    Inscription : Février 2006
    Messages : 12 840
    Billets dans le blog
    1
    Par défaut
    Citation Envoyé par cpalperou Voir le message
    Toutefois, il me semble que vos solutions permettent de garder toutes les valeurs numériques et de supprimer les strings.
    Exact. C'est ce qu'on nomme "liste en intension", où on écrit une liste 2 à partir d'un traitement direct sur une liste 1. Là le traitement c'est "garder les int/float" donc effectivement on garde tout.

    Citation Envoyé par cpalperou Voir le message
    Je souhaite en fait, garder uniquement la 1ère partie numérique.
    Dès qu'il y a un string : stop !
    Pas compliqué mais là on ne peut plus passer en liste par intension. Là il faut écrire l'algorithme complet qui crée une seconde série à partir d'une boucle sur la première et qui stoppe dès que l'élément n'est plus bon. Ensuite on remplace la première par la seconde.
    Mais bon, écrire un algo de ce type c'est normalement faisable par n'importe quel débutant Python...
    Code python : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    import pandas as pd
    test = pd.Series([1, 2, 3, "date", 5, 6, 7])
     
    tmp=list()
    for t in test:
    	if not isinstance(t, int): break
    	tmp.append(t)
    # for
     
    test=pd.Series(tmp)
    print(test)

    Une fois qu'on a l'algo, on peut alors chercher plus élégant. Mais déjà c'est quoi plus élégant en Python? Plus élégant c'est moins de variables, moins d'instructions tout en gardant la lisibilité (donc pas de lignes énormes). Par exemple ici c'est éviter le append() gros consommateur. On peut par exemple incrémenter un indice et quitter quand l'élément n'est plus bon. Suffit alors de récupérer ensuite ce qui ne va que jusqu'à l'indice
    Code python : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    import pandas as pd
    test = pd.Series([1, 2, 3, "date", 5, 6, 7])
     
    for (i, t) in enumerate(test):
    	if not isinstance(t, int): break
     
    test=pd.Series(test[:i])
    print(test)
    Mon Tutoriel sur la programmation «Python»
    Mon Tutoriel sur la programmation «Shell»
    Sinon il y en a pleins d'autres. N'oubliez pas non plus les différentes faq disponibles sur ce site
    Et on poste ses codes entre balises [code] et [/code]

  7. #7
    Expert confirmé
    Avatar de jurassic pork
    Homme Profil pro
    Bidouilleur
    Inscrit en
    Décembre 2008
    Messages
    4 246
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations professionnelles :
    Activité : Bidouilleur
    Secteur : Industrie

    Informations forums :
    Inscription : Décembre 2008
    Messages : 4 246
    Par défaut
    Hello,
    en plus compact grâce à la fonction takewhile du module itertools :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    import itertools
    import pandas as pd
    test = pd.Series(list(itertools.takewhile(lambda x: type(x) == int, [1, 2, 3, "date", 5, 6, 7])))
    print(test)
    On prend les éléments tant que ceux sont des entiers et on arrête dès que cette condition n'est plus vraie.

    Ami calmant, J.P

  8. #8
    Membre prolifique
    Avatar de Sve@r
    Homme Profil pro
    Ingénieur développement logiciels
    Inscrit en
    Février 2006
    Messages
    12 840
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Oise (Picardie)

    Informations professionnelles :
    Activité : Ingénieur développement logiciels
    Secteur : Aéronautique - Marine - Espace - Armement

    Informations forums :
    Inscription : Février 2006
    Messages : 12 840
    Billets dans le blog
    1
    Par défaut
    Citation Envoyé par jurassic pork Voir le message
    en plus compact grâce à la fonction takewhile du module itertools
    Ah oui mais là où est l'élégance ??? C'est comme celui qui court un marathon et où on lui dit "hey il tu sais que tu peux prendre une moto" ???

    (en fait je connaissais pas...)

    Citation Envoyé par jurassic pork Voir le message
    test = pd.Series(list(itertools.takewhile(lambda x: type(x) == int, [1, 2, 3, "date", 5, 6, 7])))
    Attention, il faut éviter type(truc) == xxx car ça ne gère pas l'héritage. Si par exemple tu as un truc qui hérites d'un int, ton truc bien qu'ayant toutes les caractéristiques qui en font un int n'en est quand-même pas un et le test sera faux.
    Préférer isinstance() qui, lui, gère l'héritage (et qui gère aussi les possibiltiés multiples)... test = pd.Series(list(itertools.takewhile(lambda x: isinstance(x, (int, float)), [1, 2, 3, "date", 5, 6, 7])))
    Mon Tutoriel sur la programmation «Python»
    Mon Tutoriel sur la programmation «Shell»
    Sinon il y en a pleins d'autres. N'oubliez pas non plus les différentes faq disponibles sur ce site
    Et on poste ses codes entre balises [code] et [/code]

  9. #9
    Membre Expert
    Avatar de MPython Alaplancha
    Homme Profil pro
    Paysan à 3 francs six sous
    Inscrit en
    Juin 2018
    Messages
    925
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Pyrénées Orientales (Languedoc Roussillon)

    Informations professionnelles :
    Activité : Paysan à 3 francs six sous
    Secteur : Agroalimentaire - Agriculture

    Informations forums :
    Inscription : Juin 2018
    Messages : 925
    Billets dans le blog
    8
    Par défaut
    Bonjour,
    Citation Envoyé par jurassic pork
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
     
    test = pd.Series(list(itertools.takewhile(lambda x: type(x) == int, [1, 2, 3, "date", 5, 6, 7])))
    Il n'est pas nécessaire de convertir le générateur en liste:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    test = pd.Series(itertools.takewhile(lambda x: type(x) == int, [1, 2, 3, "date", 5, 6, 7]))

  10. #10
    Membre prolifique
    Avatar de Sve@r
    Homme Profil pro
    Ingénieur développement logiciels
    Inscrit en
    Février 2006
    Messages
    12 840
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Oise (Picardie)

    Informations professionnelles :
    Activité : Ingénieur développement logiciels
    Secteur : Aéronautique - Marine - Espace - Armement

    Informations forums :
    Inscription : Février 2006
    Messages : 12 840
    Billets dans le blog
    1
    Par défaut
    Citation Envoyé par Hominidé Voir le message
    Il n'est pas nécessaire de convertir le générateur en liste
    Ben si car le truc a besoin d'appeler len() et (enfin chez-moi, sous P3.7.3) il me dit qu'un takewhile n'a pas de len().

    On peut toutefois faire une concession car une liste qui ne change pas n'a effectivement pas besoin d'être liste. Un tuple suffit.
    test = pd.Series(tuple(itertools.takewhile(lambda x: isinstance(x, int), [1, 2, 3, "date", 5, 6, 7]))).

    (et n'oublie pas isinstance() à préférer au test direct sur un type )
    Mon Tutoriel sur la programmation «Python»
    Mon Tutoriel sur la programmation «Shell»
    Sinon il y en a pleins d'autres. N'oubliez pas non plus les différentes faq disponibles sur ce site
    Et on poste ses codes entre balises [code] et [/code]

  11. #11
    Membre Expert
    Avatar de MPython Alaplancha
    Homme Profil pro
    Paysan à 3 francs six sous
    Inscrit en
    Juin 2018
    Messages
    925
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Pyrénées Orientales (Languedoc Roussillon)

    Informations professionnelles :
    Activité : Paysan à 3 francs six sous
    Secteur : Agroalimentaire - Agriculture

    Informations forums :
    Inscription : Juin 2018
    Messages : 925
    Billets dans le blog
    8
    Par défaut
    Citation Envoyé par Sve@r Voir le message
    Ben si car le truc a besoin d'appeler len() et (enfin chez-moi, sous P3.7.3) il me dit qu'un takewhile n'a pas de len().

    On peut toutefois faire une concession car une liste qui ne change pas n'a effectivement pas besoin d'être liste. Un tuple suffit.
    test = pd.Series(tuple(itertools.takewhile(lambda x: isinstance(x, int), [1, 2, 3, "date", 5, 6, 7]))).

    (et n'oublie pas isinstance() à préférer au test direct sur un type )
    Sur linux:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    >>> import itertools
    >>> import pandas as pd
    >>> test = pd.Series(itertools.takewhile(lambda x: isinstance(x, int), [1, 2, 3, "date", 5, 6, 7]))
    >>> print(test)
    0    1
    1    2
    2    3
    dtype: int64
    >>>

  12. #12
    Membre Expert
    Avatar de MPython Alaplancha
    Homme Profil pro
    Paysan à 3 francs six sous
    Inscrit en
    Juin 2018
    Messages
    925
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Pyrénées Orientales (Languedoc Roussillon)

    Informations professionnelles :
    Activité : Paysan à 3 francs six sous
    Secteur : Agroalimentaire - Agriculture

    Informations forums :
    Inscription : Juin 2018
    Messages : 925
    Billets dans le blog
    8
    Par défaut
    J'utilise Python 3.8.10...

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

Discussions similaires

  1. Réponses: 8
    Dernier message: 31/03/2013, 20h28
  2. Suppression des valeurs non numériques
    Par sniper75 dans le forum SAS Base
    Réponses: 10
    Dernier message: 28/01/2013, 15h10
  3. Réponses: 4
    Dernier message: 23/12/2010, 09h35
  4. Récupérer valeur non numérique d'un spreadsheet
    Par timeis dans le forum Général JavaScript
    Réponses: 0
    Dernier message: 15/10/2010, 09h38
  5. [WPF] Storyboard et valeurs non numérique
    Par Invité dans le forum Framework .NET
    Réponses: 3
    Dernier message: 19/11/2007, 20h07

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