python creazione unico file

Linguaggi di programmazione: php, perl, python, C, bash e tutti gli altri.
Scrivi risposta
lcu
Prode Principiante
Messaggi: 53
Iscrizione: domenica 26 febbraio 2012, 17:05

python creazione unico file

Messaggio da lcu »

Ciao a tutti,
avrei bisogno di una mano..
Io ho nove file del genere(ne riporto solo 2):

Codice: Seleziona tutto

n271962  pos: 172       1
n280112  pos: 101       3
n289944  pos: 70        5
n412898  pos: 671       1
n280112  pos: 104       2
n281197  pos: 849       1
n414174  pos: 2015      1
n282725  pos: 207       1
n284466  pos: 286       2
n271245  pos: 2540      1
n270781  pos: 3818      2
n284344  pos: 3404      2
n278240  pos: 692       2
n278240  pos: 693       3

Codice: Seleziona tutto

n275269  pos: 1749      1
n414332  pos: 3374      1
n263625  pos: 369       4
n414364  pos: 1830      2
n288825  pos: 162       1
n264912  pos: 710       3
n292802  pos: 1407      4
n276765  pos: 34        1
n290900  pos: 1943      5
n264420  pos: 921       2
n269255  pos: 2073      1
n74983   pos: 11        4
n290919  pos: 473       2
n280873  pos: 1764      1
n289773  pos: 1559      3
Come si può vedere nel primo file nelle prime due colonne posso avere delle ripetizioni ma in posizioni diverse

Codice: Seleziona tutto

n278240  pos: 692       2
n278240  pos: 693       3
oppure posso avere codici della prima e seconda colonna che si hanno solo in un file e non negli altri 8.
La terza colonna sono invece il numero di sequenze che mi si allineano a quel codice in quella posizione.
Io ho bisogno di un unico file, in cui in prima e seconda colonna si abbiano tutti i codici con tutte le posizioni possiibli elencate, senza ripetizioni (per esempio

Codice: Seleziona tutto

n278240  pos: 692  
può esserci in 2 dei 9 file,ma io nel file unico finale lo voglio preso solo una volta) 
e nelle altre 9 colonne voglio i count(cioè il numero di sequenze) che corrispondo a quel codice ed a quella posizione. Nel caso non ci fosse devo metterci uno zero.

Per esempio a

Codice: Seleziona tutto

n278240  pos: 692   
per il primo file devo mettere 2, nel secondo file postato non c'è quindi in colonna metto 0.
Mi deve uscire un file del genere(a parte i codici in prima colonna che sono diversi):

Codice: Seleziona tutto

mmu-mir-219-1 pos: 12   0       0       0       10      0       4       0       4       2
mmu-mir-709 pos: 9      0       0       1       0       0       0       0       0       0
mmu-mir-423 pos: 58     0       0       8       3       6       1       0       1       4
mmu-mir-423 pos: 59     3       1       1       4       0       8       0       0       1
mmu-mir-3057 pos: 19    0       0       0       0       6       0       0       0       0
mmu-mir-3057 pos: 18    0       13      0       0       0       0       0       1       0
Io ho scritto una cosa del genere:

Codice: Seleziona tutto

#!/usr/bin/python

from sys import argv
from collections import defaultdict


inputfile1=open(argv[1],'r')
inputfile2=open(argv[2],'r')
inputfile3=open(argv[3],'r')
inputfile4=open(argv[4],'r')
inputfile5=open(argv[5],'r')
inputfile6=open(argv[6],'r')
inputfile7=open(argv[7],'r')
inputfile8=open(argv[8],'r')
inputfile9=open(argv[9],'r')
outputfile=open(argv[10],'w')

Lista1 = defaultdict(list)
Lista2 = defaultdict(list)
Lista3 = defaultdict(list)
Lista4 = defaultdict(list)
Lista5 = defaultdict(list)
Lista6 = defaultdict(list)
Lista7 = defaultdict(list)
Lista8 = defaultdict(list)
Lista9 = defaultdict(list)
Listaoutput=defaultdict(list)

for line in inputfile1:        tokens=line.strip().split('\t')
        pos = tokens[0]+tokens[1]
        Lista1[pos].append((tokens[2]))

for line in inputfile2:
        tokens=line.strip().split('\t')
        pos = tokens[0]+tokens[1]
        Lista2[pos].append((tokens[2]))

for line in inputfile3:
        tokens=line.strip().split('\t')
        pos = tokens[0]+tokens[1]
        Lista3[pos].append((tokens[2]))

for line in inputfile4:
        tokens=line.strip().split('\t')
         pos = tokens[0]+tokens[1]
        Lista4[pos].append((tokens[2]))

for line in inputfile5:
        tokens=line.strip().split('\t')
        pos = tokens[0]+tokens[1]
        Lista5[pos].append((tokens[2]))

for line in inputfile6:
        tokens=line.strip().split('\t')
        pos = tokens[0]+tokens[1]
        Lista6[pos].append((tokens[2]))

for line in inputfile7:
        tokens=line.strip().split('\t')
        pos = tokens[0]+tokens[1]
        Lista7[pos].append((tokens[2]))

for line in inputfile8:
        tokens=line.strip().split('\t')
        pos = tokens[0]+tokens[1]
        Lista8[pos].append((tokens[2]))

for line in inputfile9:
        tokens=line.strip().split('\t')
        pos = tokens[0]+tokens[1]
        Lista9[pos].append((tokens[2]))

Listacompleta=list(set(Lista1.keys()) | set(Lista2.keys()) | set(Lista3.keys()) | set(Lista4.keys()) | set(Lista5.keys()) | set(Lista6.keys()) | set(Lista7.keys()) | set(Lista8.keys()) | set(Lista9.keys()))

inputfile1.close
inputfile2.close
inputfile3.close
inputfile4.close
inputfile5.close
inputfile6.close
inputfile7.close
inputfile8.close
inputfile9.close

for mir in Listacompleta:
        if mir is not Lista1.keys():
                Lista1[mir].append(('0'))
        if mir is not Lista2.keys():
                Lista2[mir].append(('0'))
        if mir is not Lista3.keys():
                Lista3[mir].append(('0'))
        if mir is not Lista4.keys():
                Lista4[mir].append(('0'))
        if mir is not Lista5.keys():
                Lista5[mir].append(('0'))
        if mir is not Lista6.keys():
                Lista6[mir].append(('0'))
        if mir is not Lista7.keys():
                Lista7[mir].append(('0'))
        if mir is not Lista8.keys():
                Lista8[mir].append(('0'))
        if mir is not Lista9.keys():
                Lista9[mir].append(('0'))
in cui ho in input i 9 file che saranno le 9 colonne come le voglio io disposte, poi faccio dei dizionari, gli dico di prendere coem chiave il codice e la posizione.
Creo un file unico unione dei 9 file. A questo punto dal file totale scorro i singoli 9 file, e se non trovo la chiave ci metto 0, altrimenti il counts.
Ora io non riesco a far venire poi il file unico che mi servirebbe, non riesco a farlo stampare.. mi sono bloccata.. non riesco a fargli incolonnare le 9 colonne e quindi a fare le righe con ogni riga nome codice-posizione-9 counts corrispondenti (o 0 se non ce ne sono..)..
Spero di essermi spiegata..
Grazie per l'aiuto
l3on4rdo

Re: python creazione unico file

Messaggio da l3on4rdo »

Partiamo passo passo :)
I file che devi leggere hanno dei nomi particolari?
Per "particolari" intendo qualcosa di facilmente generabile... tipo file1.txt file2.txt e così via (in cui cambia solo un numero), o altri nomi ma di questo tipo.

Oppure hanno nomi "casuali" ma sono contenuti in una stessa directory?
Ultima modifica di l3on4rdo il martedì 10 aprile 2012, 12:52, modificato 1 volta in totale.
l3on4rdo

Re: python creazione unico file

Messaggio da l3on4rdo »

Inoltre, quando ti capita una ripetizione, come ti regoli?
Prendi solo la prima?
Mi riferisco al fatto che tu nella ripetizione:

Codice: Seleziona tutto

n278240  pos: 692       2
n278240  pos: 693       3
hai scelto la prima posizione e hai trascurato la seconda.
Di conseguenza nel file finale ci sarà un 2 riferito a questo valore e a questo file, e non un 3.

Come ti regoli?
lcu
Prode Principiante
Messaggi: 53
Iscrizione: domenica 26 febbraio 2012, 17:05

Re: python creazione unico file

Messaggio da lcu »

Io ho 9 file che hanno nomi abbastanza differenti. Si chiamano mMb8,mMb21,P419_basal e così via..Posso anche modificare il loro nome, però le colonne devono essere così: le prime 3 colonne mMb#, le altre 3 #_basal, le ultime 3 #_diff...Per questo nello script gli do io l'input così posso scrivere i 9 file di input nell'ordine che voglio.. o almeno questa era la mia idea..

per quanto riguarda la ripetizione, forse non mi sono spiegata bene io..quelle due che ho messo sono diverse, perchè sono due posizioni differenti, quindi devo prenderle entrambe nel file unico.
Cioè nel file unico devo avere nelle prime due colonne

Codice: Seleziona tutto

n278240  pos: 692  
n278240  pos: 693   
ed i count(quelli in terza colonna) sono nel caso del primo file 2 e 3. Per esempio nel secondo file postato io non ho

Codice: Seleziona tutto

n278240  pos: 692    
n278240  pos: 693    
e quindi nella colonna corrispondente al secondo file devo avere 0.
l3on4rdo

Re: python creazione unico file

Messaggio da l3on4rdo »

Ok, ora vado a pranzo e appena ho un minuto ti butto giù due righe di codice, per come risolverei io la faccenda.
Se non hanno dei nomi facilmente ricostruibili con una funzione, basta che stanno tutti in una directory e invece di passare ogni path, passi solo il path della directory e il programma ti apre quello che c'è dentro. Io la gestirei così.
Ovviamente va lasciata anche la gestione dei nomi dei file passati uno ad uno.
Ma per entrambe le cose (sia come pulizia del codice sia come facilità di "revisione) ti conviene usare il modulo argparse.
Se intanto vuoi dargli un'occhiata, qui c'è la documentazione.

Ciao

ps: mi posti per cortesia l'output del comando:

Codice: Seleziona tutto

python --version
lcu
Prode Principiante
Messaggi: 53
Iscrizione: domenica 26 febbraio 2012, 17:05

Re: python creazione unico file

Messaggio da lcu »

ecco qui:
Python 2.6.4

Grazie
maiker
Prode Principiante
Messaggi: 4
Iscrizione: martedì 10 aprile 2012, 17:44

Re: python creazione unico file

Messaggio da maiker »

Ovviamente va lasciata anche la gestione dei nomi dei file passati uno ad uno.Immagine
l3on4rdo

Re: python creazione unico file

Messaggio da l3on4rdo »

@maiker
Non t'ho capito.
lcu
Prode Principiante
Messaggi: 53
Iscrizione: domenica 26 febbraio 2012, 17:05

Re: python creazione unico file

Messaggio da lcu »

Non ho capito se mi sono spiegata... quindi la faccio semplice.. immaginiamo di avere tre file per comodità con 3 colonne(come i miei file nome-posizione-count che si allineano su quei nomi):

Codice: Seleziona tutto

pippo    x    2
pippo    y    3 
pluto     x    6

Codice: Seleziona tutto

pippo       x    4
minnie     k    56
paperino  z    3

Codice: Seleziona tutto

pippo      y     6
pluto       x    7
io voglio un file unico in cui ho

Codice: Seleziona tutto

pippo x     
pippo y
pluto x
minnie k
paperino z

e poi unire i 3 file dopo che ho fatto la lista della prima e seconda colonna(nome-posizione)

Codice: Seleziona tutto

pippo x       2     4    0
pippo y       3     0     6
pluto x        6     0     7
minnie k     0     56    0 
paperino z   0    3      0 
Penso che il mio script funga fino ad un certo punto, non so come dirgli di stampare così le colonne una accanto all'altra dopo che ho fatto le liste..
Ultima modifica di lcu il martedì 10 aprile 2012, 23:04, modificato 1 volta in totale.
l3on4rdo

Re: python creazione unico file

Messaggio da l3on4rdo »

Ti sei spiegata bene (almeno per me).
Purtroppo non ho avuto tanto tempo per completare lo script, testarlo e postarlo.
Ho solo buttato giù un abbozzo.

Domani te lo posto.

ps:
non ho preso in considerazione l'idea di "correggere" il tuo, perché sinceramente e senza offesa è di difficile lettura :)
lcu
Prode Principiante
Messaggi: 53
Iscrizione: domenica 26 febbraio 2012, 17:05

Re: python creazione unico file

Messaggio da lcu »

Si ho immaginato! Io sto provando a farlo in altra maniera.. aspetto anche il tuo così vedo più punti di vista.. sempre se il mio riesce!!
Grazie mille
l3on4rdo

Re: python creazione unico file

Messaggio da l3on4rdo »

Sto avendo problemi con la connessione ad internet di casa.
Il che significa che ho difficoltà a consultare la documentazione online e a postare i miei "progressi".
Praticamente ogni due minuti si disconnette.
Domani dovrei essere in facoltà, cerco di postare da lì.

ciao
Avatar utente
jaro
Prode Principiante
Messaggi: 33
Iscrizione: venerdì 11 febbraio 2011, 23:21

Re: python creazione unico file

Messaggio da jaro »

Ok, ho provato a cimentarmi su questo ed ecco il risultato. Non sarà il massimo, ma ho fatto qualche prova e sembra che funzioni. Mi rimetto alla clemenza dei programmatori veri qui presenti :)

Codice: Seleziona tutto

#! /usr/bin/env python
from sys import argv

#apro i file di input, che possono anche essere in numero diverso da nove...
infiles=[open(filename,"r") for filename in argv[1:-1]]
# ... e mi servira' sapere quanti sono.
n_infiles=len(infiles)

#creo un dizionario le cui chiavi sono tuple con le stringhe delle prime due
#colonne e i cui argomenti sono liste contenenti quello che dovrebbe venire
#nelle colonne successive (ok, come spiegazione fa schifo. Spero che comunque
#si capisca) e chiudo i file di input.
lines=dict()
for file_no in range(n_infiles):
    for line in infiles[file_no]:
        line=line.strip().split("\t")
        if len(line)!=3:
            continue
        k=tuple(line[:2])
        if k not in lines:
            lines[k]=[0 for i in range(n_infiles)]
        lines[k][file_no]=line[2]
    infiles[file_no].close()

#apro il file di output, converto in stringhe gli elementi del dizionario
#e ce li scrivo sopra
outfile=open(argv[-1],"w")
for k in lines:
    line="%s\t%s%s\n"%(k+("\t%s"*n_infiles%tuple(lines[k]),))
    outfile.write(line)
    
outfile.close()
P.s. Il tutto è basato sull'ipotesi che gli elementi delle varie colonne siano separati da caratteri di tabulazione. Una rapida scorsa al tuo codice mi ha dato l'impressione che sia così.
Avatar utente
jaro
Prode Principiante
Messaggi: 33
Iscrizione: venerdì 11 febbraio 2011, 23:21

Re: python creazione unico file

Messaggio da jaro »

jaro ha scritto: Ok, ho provato a cimentarmi su questo ed ecco il risultato
Scusa, dimenticavo le istruzioni per l'uso. Va avviato dal terminale dandogli come parametri i nomi dei file di input e di quello di output (userà come file di output l'ultimo nome che gli dai).
Scrivi risposta

Ritorna a “Programmazione”

Chi c’è in linea

Visualizzano questa sezione: steff e 6 ospiti