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

R Discussion :

Opération data table


Sujet :

R

  1. #1
    Membre à l'essai
    Homme Profil pro
    Consultant Datascientist
    Inscrit en
    Mai 2016
    Messages
    5
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 33
    Localisation : France, Paris (Île de France)

    Informations professionnelles :
    Activité : Consultant Datascientist

    Informations forums :
    Inscription : Mai 2016
    Messages : 5
    Par défaut Opération data table
    Bonjour,

    Après un peu de recherches, je n'ai pas trouvé de réponses à mes questions.

    J'ai une table assez volumineuse (1400000x230) sur laquelle je travaille, et mes data.frame tuent ma machine avant de fournir un résultat.... je cheche donc à travailler avec des data.table, et donc à "convertir mon code"

    L'idée est la suivante : je recherche des mots-clefs dans ma table, et si je le rencontre, je le remplace par le nom de sa colonne.
    ref = c(Actif, Active)
    C1 C2 C3 C4 C5 C6 C7 C8
    Active NA NA Inactif Blabla Actif NA NA
    devient :
    C1 C2 C3 C4 C5 C6 C7 C8
    C1 NA NA Inactif Blabla C6 NA NA
    Une fois les changements faits, je collapse en enlevant les "NA" et "Inactif" pour n'obtenir qu'une seule colonne :
    NomQuelconque
    "C1 & Blabla & C6"
    Voilà mon code sur les data.frame :

    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
    20
    21
    22
    23
     
    Data = fread (data.csv, blabla)
    Data2 = as.data.frame (Data)
     
    sfInit(parallel=T, cpus=8, type='SOCK')
     
    #remplacement des termes Active/Actif par le nom de colonne
    res.1 = sfLapply(1:ncol(Data2),function(x,Data2){
        vecteur = Data2[,x]
        vecteur[(!is.na(vecteur)) & (vecteur=="Active" | vecteur=="Actif")] = colnames(Data)[x]
        return(vecteur)
    }, Data2=Data2)
    #sur des gros volumes ma RAM (16Go) explose dans cette boucle
     
    #on met le résultat sous forme de matrice
    res.m = matrix(unlist(res), nrow=nrow(Data2), byrow=F)
     
    #collapse
    res.f = sfApply(res.m,1,function(x){
        return(paste0(x[(!is.na(x)) & (x!="Inactif") & (x!="Inactive")], collapse = " & "))
    })
     
    sfStop()
    En espérant avoir été clair,
    Merci d'avance pour votre aide/vos conseils,

    Guillaume

  2. #2
    Membre émérite

    Homme Profil pro
    Cyber Security & AI
    Inscrit en
    Février 2009
    Messages
    506
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Oise (Picardie)

    Informations professionnelles :
    Activité : Cyber Security & AI

    Informations forums :
    Inscription : Février 2009
    Messages : 506
    Billets dans le blog
    2
    Par défaut
    Bonjour,

    Je comprends mal l'objectif que tu cherches. Mais, tes tables de 1 million de lignes et 230 colonnes, tout en sachant que R met systématiquement la mémoire en RAM. Alors avec une Machine 16 Go, dont 1/4 est pris par le système d'exploitation et la copie de ta table Data(pour une cellule à 16bits cela fait environs 5Go) en Data et Data2. Il ne doit pas te rester grand-chose comme mémoire.

    Au plaisir de te lire.

  3. #3
    Membre à l'essai
    Homme Profil pro
    Consultant Datascientist
    Inscrit en
    Mai 2016
    Messages
    5
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 33
    Localisation : France, Paris (Île de France)

    Informations professionnelles :
    Activité : Consultant Datascientist

    Informations forums :
    Inscription : Mai 2016
    Messages : 5
    Par défaut
    Chaque colonne représente une propriété chimique qui est NA, active ou inactive.
    Chaque ligne est une molécule.

    L'objectif est de faire une synthèse des propriétés chimiques actives, et ce pour chaque molécule.
    Une fois cette information extraite, je pourrai croiser mes molécules avec d'autres informations.
    C'est en gros l'inverse d'une mise à plat.

    Le code que j'ai est bien et fonctionne sur de petits volumes (j'ai essayé avec 800lignes), mais la structure data.frame n'est pas optimale : il va me créer 230 vecteurs à 1m4 lignes dans la première partie, et là c'est le drame...

    Effectivement, le simple chargement des table me bouffe 7.5Go de RAM...
    Je voulais alors savoir s'il n'existait pas des propriétés propres aux data.table permettant de réaliser ces opérations inplace, et ainsi optimiser mon code (en m'évitant entre autre de passer par des data.table et de créer des vecteurs temporaires)).

    merci d'avance

  4. #4
    Membre émérite

    Homme Profil pro
    Cyber Security & AI
    Inscrit en
    Février 2009
    Messages
    506
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Oise (Picardie)

    Informations professionnelles :
    Activité : Cyber Security & AI

    Informations forums :
    Inscription : Février 2009
    Messages : 506
    Billets dans le blog
    2
    Par défaut
    Guillaume,

    Je ne suis pas un spécialiste du calcul distribuer avec Snow, mais

    Code R : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    sfLapply(1:ncol(Data2),function(x,Data2){
        vecteur = Data2[,x]
        vecteur[(!is.na(vecteur)) & (vecteur=="Active" | vecteur=="Actif")] = colnames(Data)[x]
        return(vecteur)
    }, Data2=Data2)

    Ce que je redoute c'est que tu copies dans ta fonction function(x,Data2), Data2 par valeurs pour chaque thread.

    Le premier conseil que je pourrais te donner sans aucune certitude. C'est de ne pas passer par Snow dans un premier temps pour cette raison.

    Par contre, si tu veux faire des jeux avec de grosses tables et du calcul distribué, pense à SparkR et à commander plusieurs serveurs .

    Au plaisir.

  5. #5
    Membre à l'essai
    Homme Profil pro
    Consultant Datascientist
    Inscrit en
    Mai 2016
    Messages
    5
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 33
    Localisation : France, Paris (Île de France)

    Informations professionnelles :
    Activité : Consultant Datascientist

    Informations forums :
    Inscription : Mai 2016
    Messages : 5
    Par défaut
    Il me semblait que SparkR était encore en phase de dev (mais je n'ai pas regardé la 1.6 encore, qui est à priori un peu meilleure).

    Sans paralléliser, ça tourne (bon, faut juste pas être pressé). Sur peu de lignes, ça tourne.
    Mais au-delà des solutions de distribution des calculs, c'est peut être la façon dont je pense le code qui est à reprendre : il faudrait que je trouve un moyen de parcourir ma matrice et, quand j'identifie un des termes recherchés, savoir retrouver sa position [i,j] et donc écraser la valeur par le nom de la colonne j.

    Je creuse différentes pistes et je reviendrai vers vous si je finis par trouver.
    (Si vous avez d'autres idées, ne pas hésiter)

    Merci

  6. #6
    Membre à l'essai
    Homme Profil pro
    Consultant Datascientist
    Inscrit en
    Mai 2016
    Messages
    5
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 33
    Localisation : France, Paris (Île de France)

    Informations professionnelles :
    Activité : Consultant Datascientist

    Informations forums :
    Inscription : Mai 2016
    Messages : 5
    Par défaut
    Mes méninges ont fumées mais voilà que j'ai fini par touver une solution bien plus rapide !

    J'ai défini la fonction suivante :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
     
    Data_Test = fread('machin.csv',blabla)
     
    replace.active = function(Data) {
        for (i in names(Data))
            Data[(!is.na(get(i))) & (get(i)=="Active" | get(i)=="Actif") ), i:=i,with=F]
    }
     
    replace.active(Data_Test)
     
    #Une fois que les "Actifs" sont remplacés, le collapse se fait tout seul
    Et c'est magique, en 50s tous mes remplacement sont faits.

    Avantage : pas d'explosion de RAM, pas de création de table intermédiaire !

    Merci pour vos conseils

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

Discussions similaires

  1. Opérations sur tables jointes
    Par fikou dans le forum VB.NET
    Réponses: 3
    Dernier message: 10/02/2008, 15h19
  2. button dans une data table
    Par Nizarazu9 dans le forum JSF
    Réponses: 8
    Dernier message: 24/07/2007, 10h46
  3. paginer une data table en jdevelopper
    Par mans27 dans le forum JSF
    Réponses: 3
    Dernier message: 20/04/2007, 11h05
  4. data table en jsf
    Par mans27 dans le forum JSF
    Réponses: 2
    Dernier message: 17/03/2007, 18h24
  5. [Oracle 9.1] Opérations sur tables très proches...
    Par ftrifiro dans le forum Oracle
    Réponses: 7
    Dernier message: 10/10/2005, 14h10

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