Récupérer les contenus des logs comme Data Frame

Résolu
FerhatYous Messages postés 22 Statut Membre -  
FerhatYous Messages postés 22 Statut Membre -
Bonjour à tous,

J'ai des fichiers logs que je manipule sur jupyter notebook, j'ai toutes les colonnes qui contiennent un text de cette manière :
ligne 1 : a = " quelque chose" b="autre chose" c="autre chose encore " ..etc 
ligne 2 : a = " quelque chose" b="autre chose" c="autre chose encore " ..etc
ligne 3 : a = " quelque chose" b="autre chose" c="autre chose encore " ..etc
....


Ce que je voudrais faire, c'est extraire toutes les valeurs entre guillemets et les mettre en ligne et ce pour tout le
dataframe
, comme ceci :

a                  b                c
quelque chose autre chose autre chose encore
quelque chose autre chose autre chose encore
quelque chose autre chose autre chose encore


J'ai fait ceci (après avoir transformé le contenu de la colonne en liste) :

liste = []
for i in col_en_liste:
    string = re.compile("\"(.*?)\"").findall(i)  
    liste.append(string)


... donc ça parcourt la colonne et met en ligne chaque élément entre guillemets, et ça fait ça pour tout le
dataFrame
.

Le problème c'est que ça consomme de la mémoire cette méthode car j'ai des millions de fichiers.

Pourriez-vous s'il vous plaît me donner une méthode moins gourmande en terme de mémoire ? Peut-être avec les fonctions de
pandas
si ça consomme pas de la mémoire mais je vois pas comment faire.

Merci d'avance

1 réponse

  1. mamiemando Messages postés 33228 Date d'inscription   Statut Modérateur Dernière intervention   7 940
     
    Bonjour,

    Je me demande si ça n'est pas juste le volume de donnée qui est trop grand. Tu peux essayer quelque chose comme ça :

    import re
    import pandas as pd
    
    df_lines = None
    lines = [
        'a=" quelque chose1" b="autre chose" c="autre chose encore"',
        'a=" quelque chose2" b="autre chose" c="autre chose encore"',
        'a=" quelque chose3" b="autre chose" c="autre chose encore"',
    ]
    r = re.compile(r'(\w+)\s*=\s*"([^"]+)"')
    for line in lines:
        d = {
            k : [v]
            for k, v in r.findall(line)
        }
        df_line = pd.DataFrame(data=d)
        if df_lines is None:
            df_lines = df_line
        else:
            df_lines = df_lines.append(df_line)
    print(df_lines)


    Le problème c'est que comme l'explique cette discussion (et contrairement à ce qu'indique la documentation de
    pandas.DataFrame.append
    ), cette méthode n'est pas en place (in place) ce qui dégrade les performances et tu risques d'avoir le même problème et donc il faudra moralement autant de mémoire vive que 2x la taille du log. Son remplaçant
    pandas.concat
    semble souffrir des mêmes limitations.

    Du coup je me demande si dans ton cas passer par une
    pandas.Dataframe
    est si adapté. Peut-être qu'il est aussi simple de manipuler directement une grosse liste de dictionnaires (ainsi tu ne consommes qu'une fois la taille du log) ?

    import re
    from pprint import pprint
    
    lines = [
        'a=" quelque chose1" b="autre chose" c="autre chose encore"',
        'a=" quelque chose2" b="autre chose" c="autre chose encore"',
        'a=" quelque chose3" b="autre chose" c="autre chose encore"',
    ]
    r = re.compile(r'(\w+)\s*=\s*"([^"]+)"')
    data = [
        {
            k : [v]
            for k, v in r.findall(line)
        }
        for line in lines
    ]
    pprint(data)


    Après, si tes données sont vraiment extrêmement volumineuse et ne peuvent tenir en RAM, il faudra sans doute passer par une base de données (e.g. mysql).

    Bonne chance
    1
    1. FerhatYous Messages postés 22 Statut Membre
       
      Bonjour,
      effectivement, j'ai des données très volumineuses (3 millions de lignes). En essayant de traduire mon DataFrame en dictionnaire ça plante également.
      Je pense donc la meilleure solution est de les mettre dans une base de données.
      Merci encore pour votre retour.
      0
      1. mamiemando Messages postés 33228 Date d'inscription   Statut Modérateur Dernière intervention   7 940 > FerhatYous Messages postés 22 Statut Membre
         
        Ça ne m'étonne pas (surtout dans un jupyter notebook dans lequel les entrées sorties sont me semblent-ils encore plus lente que dans un client python ordinaire). En tout cas il ne faut jamais essayer d'afficher des milliers (et encore moins des millions) de lignes dans jupyter (de toute façon tu n'en feras rien :p).
        1
      2. FerhatYous Messages postés 22 Statut Membre > mamiemando Messages postés 33228 Date d'inscription   Statut Modérateur Dernière intervention  
         
        Merci les conseils et les indications
        0