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 :

remplacer chaines de caractères dans un fichier


Sujet :

Python

  1. #1
    Membre averti
    Homme Profil pro
    Étudiant
    Inscrit en
    Octobre 2017
    Messages
    47
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 35
    Localisation : France, Charente (Poitou Charente)

    Informations professionnelles :
    Activité : Étudiant

    Informations forums :
    Inscription : Octobre 2017
    Messages : 47
    Par défaut remplacer chaines de caractères dans un fichier
    Bonjour,

    Je chercher à remplacer des chaines de caractères en fonction de plusieurs conditions, voilà mon code:
    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
    24
    25
    26
    27
    28
    29
    30
    31
    32
    pos=[]
    ref=[]
    alt=[]	
    test=[16842,'G','C'],[16844,'T','G'],[16839,'C','T'],[16830,'T','ACCCC'],[16820,'T','GCC']
    test2=[]
    for x in test:
    	pos.append(x[0])
    	ref.append(x[1])
    	alt.append(x[2])
     
    fasta=open('rCRS.txt','r')
    seq=""
    name=""
    tmp=fasta.readlines()
    fasta.close()
    name=tmp[0][1:-1]
    count=0
    newfa=[">",name,"\n"]
    for x in tmp[1:] :
    	for y in x:
    		count+=1
    		if count in pos:
    			if y == 'G' and 'C' in alt:
    				newfa.append('W')
    			elif y == 'T' and 'G' in alt:
    				newfa.append('Z')
    			elif y == 'C' and  'T' in alt:
    				newfa.append('Y')
     
    		else:
    			newfa.append(y)
    print ''.join(newfa)
    voilà le résulat:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    CTGGTTCCTACTTCAGGGTCATAAAGCCTAAATAGCCCACACGTZCCCCTTAAAZAAGAC
    ATYACWAZG
    Le problème est que la lettre Z (ma seconde condition) apparaît à trois reprises alors qu'elle devrait être présente seulement une seule fois....
    De même si j'ai par exemple ce motif 'ACCCC' je dois le remplacer à la position 16830 si on a bien un T dans notre fichier input..

    Si quelqu’un à une idée?
    encore merci pour votre aide.
    Piotreee
    Fichiers attachés Fichiers attachés

  2. #2
    Membre Expert

    Homme Profil pro
    Ingénieur calcul scientifique
    Inscrit en
    Mars 2013
    Messages
    1 229
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Alpes Maritimes (Provence Alpes Côte d'Azur)

    Informations professionnelles :
    Activité : Ingénieur calcul scientifique

    Informations forums :
    Inscription : Mars 2013
    Messages : 1 229
    Par défaut
    Dans les boucles for, votre variable 'alt' est la même indépendamment de la valeur de x et de y. Je doute que ce soit cela qu'on veuille.

    A quoi serve les variables test ? Vous les définissez et ne vous en servez pas... Ce n'est pas là dedans que vous définissez l'ensemble des choses que vous voulez remplacer ?

  3. #3
    Membre averti
    Homme Profil pro
    Étudiant
    Inscrit en
    Octobre 2017
    Messages
    47
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 35
    Localisation : France, Charente (Poitou Charente)

    Informations professionnelles :
    Activité : Étudiant

    Informations forums :
    Inscription : Octobre 2017
    Messages : 47
    Par défaut
    Merci. Oui peut être que boucler sur ma variable test et tester les égalités serait mieux...
    La variable test est en réalité un fichier csv. Le fichier attaché est un fichier fasta (sequence ADN) organisé de la sorte:
    >nom de le sequence
    ACCCGTTTTA
    TTTC..............

    Mon fichier de sortie est le même que le fichier d entré avec les modifs en plus.
    Merci beaucoup.

  4. #4
    Expert éminent
    Homme Profil pro
    Architecte technique retraité
    Inscrit en
    Juin 2008
    Messages
    21 762
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Manche (Basse Normandie)

    Informations professionnelles :
    Activité : Architecte technique retraité
    Secteur : Industrie

    Informations forums :
    Inscription : Juin 2008
    Messages : 21 762
    Par défaut
    Salut,

    Citation Envoyé par Piotree Voir le message
    Merci. Oui peut être que boucler sur ma variable test et tester les égalités serait mieux...
    Un bon début serait de décrire plus précisément (en français) ce que vous cherchez à faire...

    - W
    Architectures post-modernes.
    Python sur DVP c'est aussi des FAQs, des cours et tutoriels

  5. #5
    Membre averti
    Homme Profil pro
    Étudiant
    Inscrit en
    Octobre 2017
    Messages
    47
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 35
    Localisation : France, Charente (Poitou Charente)

    Informations professionnelles :
    Activité : Étudiant

    Informations forums :
    Inscription : Octobre 2017
    Messages : 47
    Par défaut
    Bonjour,
    Je suis vraiment désolé pour toutes ces confusions.

    En fait, j'ai deux fichiers dont l'un est une séquence ADN fasta (il est en pièce jointe.) et le second, ici correspond à la variable test:

    Dans la variable test ici 16842 correspond à la position dans mon fichier fasta, le G est la lettre qui se trouve à cette position. Je sais également qu'à cette même position il est possible d'avoir un C. Pour cette position je veux alors changer le G en W qui correspond à la combinaison G,C (désolé, cela peut paraître un peu étrange..)

    De même dans la variable test, on peut avoir
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    test=[16830,'T','ACCCC']
    . Cela signifie qu'à la position 16830 de notre fichier fasta on doit avoir un T que l'on remplace par ACCCC.

    J'essaie de changer en premier cela: en W
    puis cela;
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    test=[16830,'T','ACCCC']
    parce que si je remplace en premier le T par ACCCC à la position 16842 nous n'aurons plus la lettre G vu que precedemment on aura remplace une lettre par 5 autres.

    J'espère être plus claire et je suis vraiment désolé pour l'incohérence de mon premier post.
    Merci pour votre aide

  6. #6
    Rédacteur/Modérateur

    Avatar de Jerome Briot
    Homme Profil pro
    Freelance mécatronique - Conseil, conception et formation
    Inscrit en
    Novembre 2006
    Messages
    20 317
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Haute Garonne (Midi Pyrénées)

    Informations professionnelles :
    Activité : Freelance mécatronique - Conseil, conception et formation

    Informations forums :
    Inscription : Novembre 2006
    Messages : 20 317
    Par défaut
    Citation Envoyé par Piotree Voir le message
    si je remplace en premier le T par ACCCC à la position 16842 nous n'aurons plus la lettre G vu que precedemment on aura remplace une lettre par 5 autres.
    C'est un problème classique. Pour le résoudre, remplace les éléments par ordre décroissant, en commençant par le dernier.

  7. #7
    Membre Expert

    Homme Profil pro
    Ingénieur calcul scientifique
    Inscrit en
    Mars 2013
    Messages
    1 229
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Alpes Maritimes (Provence Alpes Côte d'Azur)

    Informations professionnelles :
    Activité : Ingénieur calcul scientifique

    Informations forums :
    Inscription : Mars 2013
    Messages : 1 229
    Par défaut
    Essayer de faire un code plus petit.

    Au lieu d'importer un fichier, donner vous simplement une chaine de caractère au début. Adaptez les positions pour que ce soit celles sur votre chaine de caractère (donc à priori quelquechose de petit et pas de l'ordre de 16 000). Ensuite donnez nous le résultat attendu.


    Pour ce qui est du problème du parcours à l'envers, là vous ne devriez pas être confronter à ce problème puisque vous construisez une nouvelle séquence. Le problème se poserait si vous cherchiez à modifier la séquence elle même directement.

  8. #8
    Expert éminent
    Homme Profil pro
    Architecte technique retraité
    Inscrit en
    Juin 2008
    Messages
    21 762
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Manche (Basse Normandie)

    Informations professionnelles :
    Activité : Architecte technique retraité
    Secteur : Industrie

    Informations forums :
    Inscription : Juin 2008
    Messages : 21 762
    Par défaut
    Salut,

    Citation Envoyé par Piotree Voir le message
    De même dans la variable test, on peut avoir
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    test=[16830,'T','ACCCC']
    . Cela signifie qu'à la position 16830 de notre fichier fasta on doit avoir un T que l'on remplace par ACCCC.
    Si j'ai un 'T' à la position 16830, on le remplace par 'ACCCC', çà je comprends.
    Par contre:

    Citation Envoyé par Piotree Voir le message
    Dans la variable test ici 16842 correspond à la position dans mon fichier fasta, le G est la lettre qui se trouve à cette position. Je sais également qu'à cette même position il est possible d'avoir un C. Pour cette position je veux alors changer le G en W qui correspond à la combinaison G,C (désolé, cela peut paraître un peu étrange..)
    Là déjà çà devient confus car le deuxième élément de test n'a pas le même sens que précédemment et d'où sort le 'W', mystère!

    Citation Envoyé par Piotree Voir le message
    J'essaie de changer en premier cela: en W puis cela;
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    test=[16830,'T','ACCCC']
    parce que si je remplace en premier le T par ACCCC à la position 16842 nous n'aurons plus la lettre G vu que precedemment on aura remplace une lettre par 5 autres.
    Par quelle magie vous allez d'abord remplacer à la position 16842 puis à la position 16830? Si vous construisez une nouvelle chaîne de caractères à partir de... il va falloir y aller séquentiellement: 16830 sera passé lorsqu'on va arriver en 16842 et vous n'aurez rien remplacé dans la chaîne initiale, juste créé les 16xxx premiers caractères de la nouvelle chaîne/liste que vous appelez newfa.

    Si vous voulez coder, il va falloir être plus précis.

    - W
    Architectures post-modernes.
    Python sur DVP c'est aussi des FAQs, des cours et tutoriels

  9. #9
    Membre averti
    Homme Profil pro
    Étudiant
    Inscrit en
    Octobre 2017
    Messages
    47
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 35
    Localisation : France, Charente (Poitou Charente)

    Informations professionnelles :
    Activité : Étudiant

    Informations forums :
    Inscription : Octobre 2017
    Messages : 47
    Par défaut
    Bonjour,

    Merci pour vos commentaires et conseils.
    j'ai donc fais des modifications:
    La première a été de dissocier les lettres que je dois remplacer avec celles que je dois inclure :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    indel=[]  
    heteroplasmies={}    
    test=[2,'C','T'],[4,'A','T'],[5,'C','G'],[8,'T','GGG'],[15,'T','GCC'],[18,'T','ACCCC']
    for x in test:
        if len(x[2]) > 1 :
    		tmp=x[0],x[2]
    		indel.append(tmp)
        else:
            heteroplasmies[x[0]]='_'.join(x[1:3])
    Ici, ma liste indel contient les positions et les lettres dont le nombre est supérieur à 1.
    Pour le dico heteroplasmie, les clés sont les positions et j'ai joint les lettres : par exemple 'C','T' en C_T pour changer ce motif(C_T) en 'Z'.

    Ensuite, j'essaie de parcourir ma variable seq est de faire les changements souhaités correspondent aux differentes conditions if.
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    seq=['A','C','C','A','C','G','G','T','G','T','G','T','G','A','G','T','G','T']
    count=0
    for x in seq:
        count+=1
        for c,v in heteroplasmies.items():
            if count == c and x == 'C' and v == 'C_G':
    			seq[count]='W'
            elif x == c and x == 'C' and v == 'C_T':
    			count[count]='Z'
            elif x == c and x == 'A' and v == 'A_T':
    			count[count]='Y
    Le premier problème est que le W remplace la 6 lettre et non la cinquième.
    Je pense que ca doit venir du fait que python commence à 0?
    Le deuxième problème comme me l'a fait remarquer wiztricks, c'est que je change la position 5 avant la 2 est la 4.
    Comme il l'a suggéré, je devrais le faire sequentiellement, mais je ne vois pas trop comment faire.


    Pour la liste indel je vais trier par ordre décroissant pour ne pas être gêné par l'ajout de lettres qui changeront la taille de ma liste est donc les positions où je dois ajouter mes lettres.Je le ferai dans un second temps.

    Le résultat souhaite aurait été :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    seq=['A','Z','C','Y',W','G','G','T','G','T','G','T','G','A','G','T','G','T']
    Merci beaucoup pour votre aide.

  10. #10
    Expert éminent
    Homme Profil pro
    Architecte technique retraité
    Inscrit en
    Juin 2008
    Messages
    21 762
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Manche (Basse Normandie)

    Informations professionnelles :
    Activité : Architecte technique retraité
    Secteur : Industrie

    Informations forums :
    Inscription : Juin 2008
    Messages : 21 762
    Par défaut
    Citation Envoyé par Piotree Voir le message
    Comme il l'a suggéré, je devrais le faire sequentiellement, mais je ne vois pas trop comment faire.
    Si vous écrivez for x in seq:, vous procédez séquentiellement. Par contre, si vous ne créez pas une nouvelle liste alors les conditions de départ "bougent" et çà va être compliqué!

    De plus, "test" est une liste comprenant une position et... donc vous pouvez ranger par ordre de positions croissants et faire une boucle qui va aller de position en position.

    - W
    Architectures post-modernes.
    Python sur DVP c'est aussi des FAQs, des cours et tutoriels

  11. #11
    Membre Expert

    Homme Profil pro
    Ingénieur calcul scientifique
    Inscrit en
    Mars 2013
    Messages
    1 229
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Alpes Maritimes (Provence Alpes Côte d'Azur)

    Informations professionnelles :
    Activité : Ingénieur calcul scientifique

    Informations forums :
    Inscription : Mars 2013
    Messages : 1 229
    Par défaut
    Citation Envoyé par Piotree Voir le message
    Bonjour,

    Merci pour vos commentaires et conseils.
    j'ai donc fais des modifications:
    La première a été de dissocier les lettres que je dois remplacer avec celles que je dois inclure :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    indel=[]  
    heteroplasmies={}    
    test=[2,'C','T'],[4,'A','T'],[5,'C','G'],[8,'T','GGG'],[15,'T','GCC'],[18,'T','ACCCC']
    for x in test:
        if len(x[2]) > 1 :
    		tmp=x[0],x[2]
    		indel.append(tmp)
        else:
            heteroplasmies[x[0]]='_'.join(x[1:3])
    Ici, ma liste indel contient les positions et les lettres dont le nombre est supérieur à 1.
    Pour le dico heteroplasmie, les clés sont les positions et j'ai joint les lettres : par exemple 'C','T' en C_T pour changer ce motif(C_T) en 'Z'.

    Ensuite, j'essaie de parcourir ma variable seq est de faire les changements souhaités correspondent aux differentes conditions if.
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    seq=['A','C','C','A','C','G','G','T','G','T','G','T','G','A','G','T','G','T']
    count=0
    for x in seq:
        count+=1
        for c,v in heteroplasmies.items():
            if count == c and x == 'C' and v == 'C_G':
    			seq[count]='W'
            elif x == c and x == 'C' and v == 'C_T':
    			count[count]='Z'
            elif x == c and x == 'A' and v == 'A_T':
    			count[count]='Y
    Le premier problème est que le W remplace la 6 lettre et non la cinquième.
    Je pense que ca doit venir du fait que python commence à 0?
    Le deuxième problème comme me l'a fait remarquer wiztricks, c'est que je change la position 5 avant la 2 est la 4.
    Comme il l'a suggéré, je devrais le faire sequentiellement, mais je ne vois pas trop comment faire.


    Pour la liste indel je vais trier par ordre décroissant pour ne pas être gêné par l'ajout de lettres qui changeront la taille de ma liste est donc les positions où je dois ajouter mes lettres.Je le ferai dans un second temps.

    Le résultat souhaite aurait été :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    seq=['A','Z','C','Y',W','G','G','T','G','T','G','T','G','A','G','T','G','T']
    Merci beaucoup pour votre aide.


    Alors il y a un peu du n'importe quoi là dedans. Vous n'avez pas essayé ce code, il ne compile pas. Il manque des guillements, et count qui est un entier se voit affublé de
    ce qui ne peut absolument pas aller.


    Ensuite vous aviez des append dans votre code de départ. Là vous n'en avez plus, pourquoi ? Je vous ai demandé de changer votre code pour que l'on puisse raisonner sur un exemple plus petit tout en testant le même algorithme. Si vous changez aussi l'algorithme là on nage dans le flou, car tu ne saura pas résoudre le problème initial ...

    C'est fort dommage car ton ton post de départ aurait été celui-là avec un soin sur le code comme sur ton tout premier post et bien tu aurais eu une réponse tout de suite à ton problème. Là voici :

    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
    24
    25
    26
    27
    28
    29
    30
    31
    indel=[]  
    heteroplasmies={}    
    test=[2,'C','T'],[4,'A','T'],[5,'C','G'],[8,'T','GGG'],[15,'T','GCC'],[18,'T','ACCCC']
    for x in test:
        if len(x[2]) > 1 :
            tmp=x[0],x[2]
            indel.append(tmp)
        else:
            heteroplasmies[x[0]-1]='_'.join(x[1:3])
     
     
    seq=['A','C','C','A','C','G','G','T','G','T','G','T','G','A','G','T','G','T']
     
    new_seq = []
    for i,x in enumerate(seq):
        new_char = x
        for c,v in heteroplasmies.items():
            if i == c :
                if x == 'C' and v == 'C_G':
                    new_char='W'
                elif x == 'C' and v == 'C_T':
                    new_char='Z'
                elif x == 'A' and v == 'A_T':
                    new_char='Y'
        new_seq.append(new_char)
     
     
    seq_wait=['A','Z','C','Y','W','G','G','T','G','T','G','T','G','A','G','T','G','T']
     
    for x,y in zip(new_seq, seq_wait):
        print("%s (waited %s)"%(x,y))
    Note que dans heteroplasmies, je décale de 1 les indices, pour que cela commence à 0 (indices python). On peut faire beaucoup mieux encore, mais déjà il vous faut comprendre cette solution là et pourquoi la votre ne pouvait pas fonctionner.

  12. #12
    Membre averti
    Homme Profil pro
    Étudiant
    Inscrit en
    Octobre 2017
    Messages
    47
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 35
    Localisation : France, Charente (Poitou Charente)

    Informations professionnelles :
    Activité : Étudiant

    Informations forums :
    Inscription : Octobre 2017
    Messages : 47
    Par défaut
    Merci beaucoup IG_53

    Tu as complètement raison, j ai fais des modifs en introduisant des erreurs.
    J'essaie d'avance le soir....je crois que je vais reprendre tout ça à tête reposée ce week et poster quelque chose de plus rigoureux..
    Dsl pour ça, en tout cas en grand merci car votre aide est très précieuse et constructive.
    A tres vite

Discussions similaires

  1. [Débutant] Remplacer chaine de caractères dans un fichier
    Par bezourox dans le forum VB.NET
    Réponses: 3
    Dernier message: 08/04/2014, 08h02
  2. Remplacement de chaine de caractères dans un fichier
    Par koKoTis dans le forum Langage
    Réponses: 4
    Dernier message: 13/09/2008, 18h36
  3. Remplacer une chaine de caractère dans un fichier texte.
    Par Empty_body dans le forum VBA Access
    Réponses: 1
    Dernier message: 19/01/2008, 11h16
  4. Réponses: 14
    Dernier message: 15/06/2007, 13h59
  5. Réponses: 4
    Dernier message: 18/07/2006, 16h31

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