Extraire des lignes d'un dataframe

Résolu
Bonsoir,
J'ai ce dataframe:


j'aimerai extraire les ligne où un client il est au même temps dans l'action Block et l'action Alow, Donc je veux les lignes : 0, 2, 4 et 6.
svp, toute solution est le bienvenu
Merci d'avance

4 réponses

  1. Modérateur
    Bonjour,

    Voilà ce que je te propose :

    import io
    import pandas as pd
    
    csv = io.StringIO("""action,adresse_ip,ip_source,ip_dest,client
    block,128.03.03.29,29E9t9994,12300rtgR30,client1
    block,128.03.04.22,29E9th9994,12300Rg30,client2
    allow,128.03.05.293,29dfbfE99994,12d300R30,client1
    block,128.03.73.294,29E99fv994,1230s0R30,client3
    allow,128.03.83.295,29Egfn99994,12h300R30,client2
    allow,128.03.93.296,29E99fv994,123k00R30,client5
    allow,128.03.04.297,29E99994,12300tR30,client7
    block,128.03.01.298,29E99994,1230z0R30,client8
    block,128.03.02.299,29E99994,1230v0R30,client9""")
    
    df = pd.read_csv(csv)
    df2 = df.groupby("client", as_index=False)["action"].count()
    clients = {client for client in df2[df2["action"] >= 2]["client"]}
    print(df[df["client"].isin(clients)])


    Résultat

      action     adresse_ip     ip_source      ip_dest   client
    0 block 128.03.03.29 29E9t9994 12300rtgR30 client1
    1 block 128.03.04.22 29E9th9994 12300Rg30 client2
    2 allow 128.03.05.293 29dfbfE99994 12d300R30 client1
    4 allow 128.03.83.295 29Egfn99994 12h300R30 client2


    Est-ce que ça te va ?

    Bonne chance
    1. Bonjour,
      C'est parfait ! c'est exactement ce que je voulais.
      Merci!
      1. Modérateur
        Super :-) Bonne continuation !
    2. Bonjour,

      Désolé pour le format du dataframe, le voici :

      action, adresse_ip, ip_source, ip_dest, client
      block, ip="128.03.03.29", source="29E9t9994" ,destination="12300rtgR30" ,client1
      block, ip="128.03.04.22" ,source="29E9th9994" ,destination="12300Rg30" ,client2
      allow,ip="128.03.05.293", source="29dfbfE99994", destination="12d300R30" ,client1
      block ,ip="128.03.73.294", source="29E99fv994" ,destination="1230s0R30" ,client3
      allow, ip="128.03.83.295", source="29Egfn99994" ,destination="12h300R30", client2
      allow, ip="128.03.93.296", source="29E99fv994" ,destination="123k00R30", client5
      allow, ip="128.03.04.297", source="29E99994" ,destination="12300tR30" ,client7
      block, ip="128.03.01.298", source="29E99994" ,destination="1230z0R30", client8
      block, ip="128.03.02.299", source="29E99994" ,destination="1230v0R30" ,client9


      J'ai testé le code que vous m'avez donné, mais j'ai eu une erreur :
      " TypeError: <lambda>() got an unexpected keyword argument 'axis'"


      Sur ce nouveau dataframe, j'aimerai récupérer les lignes 1, 2,3 et 5.

      J'ai également essayé une autre méthode mais je ne suis pas sûr :

      data1 = df[df['action'] == 'Allow']
      data2 = df[df['action'] == 'Blocking']
      
      s = data1.loc[data1['client'].isin(data2['client'])]
      s2 = data2.loc[data2['client'].isin(data1['client'])]
      s = pd.concat([s,s2])
      s
      


      Merci d'avance.
      1. Modérateur
        Bonjour,

        Merci de ne PAS faire de capture d'écran. Ça n'est pratique pour personne et on ne peut pas copier ta dataframe pour faire des tests. Il vaut mieux toujours copier coller du code qu'on peut reproduire.

        Je pense que le plus simple est de faire un truc du genre :
        df2 = df.groupby("client")["client", "action"]
        df3 = df2[df2.apply(lambda row: len(row['action']) == 2, axis=1)]
        print(df3)

        ... mais sans garantie car je ne peux pas tester.

        Bonne chance