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 :

Python - Recherchev dans un intervalle (DataFrame ordonné) [Python 3.X]


Sujet :

Python

  1. #1
    Membre à l'essai
    Inscrit en
    Juillet 2008
    Messages
    10
    Détails du profil
    Informations forums :
    Inscription : Juillet 2008
    Messages : 10
    Points : 10
    Points
    10
    Par défaut Python - Recherchev dans un intervalle (DataFrame ordonné)
    Bonjour,

    Supposons que nous ayons un portefeuille ou la répartition soit 20% de demoiselles, 30% d'hommes et 50% de femmes.

    Pour simuler ce portefeuille je peux tirer un nombre aléatoire np.random.rand() entre 0 et 1 et affecter une catégorie (probabilité pondérée) comme suit :

    Intervalle Categorie Proba_cumulee
    0-20% Demoiselles 0,2
    21-50% Hommes 0,5
    51%-100% Femmes 1

    Je sais donc que je ne tomberai pas sur la valeur, c'est la raison pour laquelle je souhaite travailler en intervalle sachant que mes tables de paramétrages sont ordonnées du plus petit au plus grand.

    Par exemple, je sais que dans mon portefeuille j'ai 20% de demoiselles, 30% d'hommes et 50% de femmes.
    La méthode est alors de tirer un numéro aléatoire et s'il est <=20% j'affecte "Demoiselle", s'il est entre 20% et 50% j'affecte "Monsieur" et s'il est supérieur a 50% j'affecte "Madame"
    Bien sur pour 3 lignes je peux faire :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    for x in Base_client_RD :
        if x < 0.2 : Base_client_Sexe.append("D")
        elif x >0.2 and x < 0.5 : Base_client_Sexe.append("H")
        else : Base_client_Sexe.append("F")
    Par contre, si nous passons au niveau des départements on a 100 valeurs et si on passe au niveau des codes postaux on passe a des valeurs trop importantes pour faire de la saisie.


    Sur VBA ce que j'avais fait est :
    Code VBA : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    If Ratio < V1 Then Sheets("Portefeuille_T0").Cells(1 + i, 3).Value = Sheets("Loi_age_zone").Range("O6").Value
    If Ratio >= V1 And Ratio < V2 Then Sheets("Portefeuille_T0").Cells(1 + i, 3).Value = Sheets("Loi_age_zone").Range("O7").Value
    If Ratio >= V2 And Ratio < V3 Then Sheets("Portefeuille_T0").Cells(1 + i, 3).Value = Sheets("Loi_age_zone").Range("O8").Value


    Mais sous python, je ne vois pas.
    Il y a une méthode avec des intervalles fixes (https://stackoverflow.com -> pandas-lookup-by-pd-interval) , mais ce n'est pas mon cas.
    La méthode avec le merge.Asof ne fonctionne pas car dans la quasi totalité des cas sauf 3, cela ne renvoie rien.

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    pd.merge_asof(Part_C, Fichier_parametrage_Sexe, on='Part_C')

    Si quelqu'un a une idée, cela serait super.
    Bonne journée.

  2. #2
    Expert éminent sénior Avatar de disedorgue
    Homme Profil pro
    Ingénieur intégration
    Inscrit en
    Décembre 2012
    Messages
    4 287
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations professionnelles :
    Activité : Ingénieur intégration
    Secteur : High Tech - Opérateur de télécommunications

    Informations forums :
    Inscription : Décembre 2012
    Messages : 4 287
    Points : 12 744
    Points
    12 744
    Par défaut
    Bonjour,

    Peut-être une idée du style:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    from io import StringIO
    import pandas as pd
     
    TESTDATA=StringIO("""Intervalle;Categorie;Proba_cumulee
                      0-20%;Demoiselles;0,2
                      21-50%;Hommes;0,5
                      51%-100%;Femmes;1""")
     
    df = pd.read_csv(TESTDATA, sep=";",dtype={'Proba_cumulee' : float },decimal=b',')
     
    A=0.11
    print(df.loc[(A <= df['Proba_cumulee'])].head(1))
    Cordialement.

  3. #3
    Membre à l'essai
    Inscrit en
    Juillet 2008
    Messages
    10
    Détails du profil
    Informations forums :
    Inscription : Juillet 2008
    Messages : 10
    Points : 10
    Points
    10
    Par défaut
    Bonjour et merci, je vais regarder.

    J'ai essayé la formule ci-dessous qui fonctionne également, mais elle me pose un problème de performance, sur des petites volumétries 5000 tests cela tourne en 10 secondes, mais si veux veux lancer 500 000 j'ai un petit problème.


    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    for j in range(len(Base_client_1)):
        for k in range(len(Base_client_2)):
     
            #if Base_client_Code_Alea.iloc[[j,1]]>Base_client_2.iloc[[k,'Part_C']] and Base_client_2.iloc[[k+1,'Part_C']]> Base_client_Code_Alea.iloc[[j,1]]:
            if Base_client_1.loc[j,'Part_C']>Base_client_2.loc[k,'Part_C'] and Base_client_2.loc[k+1,'Part_C']> Base_client_1.loc[j,'Part_C']:
                Base_client_1.loc[j,'Sexe']=Base_client_2.loc[k,'Nature']
            if Base_client_2.loc[k+1,'Part_C']> Base_client_1.loc[j,'Part_C']:
                break

  4. #4
    Membre à l'essai
    Inscrit en
    Juillet 2008
    Messages
    10
    Détails du profil
    Informations forums :
    Inscription : Juillet 2008
    Messages : 10
    Points : 10
    Points
    10
    Par défaut
    Bonjour,
    j'apporte la réponse a la question que j'ai posé, car j'ai enfin trouvé.
    Il ne faut pas faire de double boucle, mais utiliser la fonction merge_asof avec les paramétrages nécessaires.
    Le résultat est quasi instantannée (520 ms) pour 5 millions de lignes.

    Dans mon cas :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
     
    Base_client_1=Base_client_1.sort_values(by='Part_C_RD')
    Base_client_3=pd.merge_asof(Base_client_1,Base_client_2,left_on='Part_C_RD',right_on='Part_C',direction ='backward')
    Attention, il faut trier le dataframe de gauche
    Les options directions permettent ensuite de faire les bonnes sélections sur intervalles.

    A bientôt pour de nouvelles aventures.

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

Discussions similaires

  1. RechercheV d'une date dans un intervalle de dates
    Par manuellelo dans le forum Excel
    Réponses: 14
    Dernier message: 03/07/2018, 15h44
  2. Recherche de dates dans un intervalle avec RechercheV
    Par manuellelo dans le forum Macros et VBA Excel
    Réponses: 0
    Dernier message: 14/11/2016, 16h39
  3. valeur contenue dans un intervalle
    Par javaSudOuest dans le forum Langage SQL
    Réponses: 10
    Dernier message: 02/12/2005, 15h12
  4. slection dans une intervalle d'enregistrement
    Par toome dans le forum Langage SQL
    Réponses: 1
    Dernier message: 30/08/2005, 15h17
  5. Réponses: 7
    Dernier message: 02/06/2003, 08h38

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