[Risolto][Python] Come spezzettare la tabella dell'esempio

Linguaggi di programmazione: php, perl, python, C, bash e tutti gli altri.
Avatar utente
BlueEyes
Entusiasta Emergente
Entusiasta Emergente
Messaggi: 1330
Iscrizione: giovedì 15 marzo 2012, 14:08

[Risolto][Python] Come spezzettare la tabella dell'esempio

Messaggio da BlueEyes »

Salve Forum.
Mi sono avvicinato a Python da poco tempo, e quindi appassionato per le ragioni che sono sinteticamente riportate nello screenshot.
Vorrei sapere come "affettare" la seguente tabella (ne riporto uno stralcio di quella completa 15000 righe x 24 colonne):

Codice: Seleziona tutto

# ----------- dummy.txt --------- 
         (*)          (*)                (*)                  (*)
 9 6 1 54983.00 I  0.031540 0.000038  0.533564 0.000042  I 0.2517073 0.0000057  1.4188 0.0045  I   -60.675    0.161    -9.124    0.340   .031510   .533610   .2517120   -60.600    -9.100  
 9 6 2 54984.00 I  0.035498 0.000015  0.533731 0.000023  I 0.2503537 0.0000059  1.2829 0.0040  I   -60.761    0.740    -9.053    0.340   .035490   .533780   .2503580   -60.600    -9.000  
 9 6 3 54985.00 I  0.039516 0.000049  0.534361 0.000032  I 0.2491601 0.0000057  1.0912 0.0040  I   -60.779    0.168    -9.019    0.340   .039500   .534470   .2491590   -60.500    -9.000  
 9 6 4 54986.00 I  0.043773 0.000049  0.535228 0.000032  I 0.2481804 0.0000055  0.8722 0.0040  I   -60.845    0.168    -9.011    0.340   .043750   .535270   .2481700   -60.600    -9.100  
 9 6 5 54987.00 I  0.048164 0.000050  0.536559 0.000031  I 0.2474214 0.0000057  0.6363 0.0039  I   -60.977    0.168    -9.061    0.340   .048040   .536590   .2474210   -60.800    -9.200  
 9 6 6 54988.00 I  0.051763 0.000050  0.537789 0.000030  I 0.2468931 0.0000054  0.4446 0.0035  I   -61.091    0.172    -9.216    0.108   .051770   .537870   .2468890   -61.200    -9.300  
 9 6 7 54989.00 I  0.055262 0.000050  0.538788 0.000030  I 0.2465087 0.0000041  0.3233 0.0034  I   -61.163    0.245    -9.475    0.125   .055210   .538870   .2465000   -61.400    -9.500  
 9 6 8 54990.00 I  0.058631 0.000051  0.539480 0.000030  I 0.2462295 0.0000041  0.2529 0.0027  I   -61.225    0.245    -9.678    0.125   .058610   .539540   .2462240   -61.500    -9.700  
 9 6 9 54991.00 I  0.061698 0.000024  0.540065 0.000029  I 0.2459726 0.0000035  0.2735 0.0027  I   -61.282    0.191    -9.672    0.340   .061700   .540110   .2459700   -61.400    -9.600  
 9 610 54992.00 I  0.064372 0.000024  0.540441 0.000029  I 0.2456633 0.0000036  0.3517 0.0025  I   -61.288    0.191    -9.480    0.340   .064320   .540580   .2456580   -61.200    -9.500  
 9 611 54993.00 I  0.067594 0.000025  0.540422 0.000029  I 0.2452479 0.0000036  0.4939 0.0025  I   -61.269    0.191    -9.281    0.340   .067490   .540420   .2452440   -61.100    -9.300  
 9 612 54994.00 I  0.071060 0.000024  0.540558 0.000029  I 0.2446650 0.0000036  0.6677 0.0028  I   -61.319    0.191    -9.200    0.340   .071070   .540620   .2446590   -61.000    -9.300  
# --------------------------------
Dovrei ricavarne una contenente le 4 colonne indicate con l'asterisco (*). I dati possono essere trattati come stringhe, non necessariamente numerici, intendo dire.
Grazie in anticipo
Allegati
preface.png
Ultima modifica di BlueEyes il venerdì 11 maggio 2012, 10:09, modificato 1 volta in totale.
l3on4rdo

Re: [Python] Come spezzettare la tabella dell'esempio

Messaggio da l3on4rdo »

Fare quello che chiedi non è difficile, se ho capito.
Leggi prima la riga (magari imponendo che la stessa non inizi con il carattere # inizi con un numero) con file.readline(), poi la "spezzi" con str.split() e ti regoli di conseguenza con gli elemeni che ti servono della lista risultante.

L'unica perplessità è che, per esempio, nella prima riga il primo campo che ti interessa è il quarto (considerando lo spazio come separatore), mentre in quella successiva è il secondo. Ma se la cosa segue la ricorsività (alternata) che si vede in questo file, non è di difficile gestione.

Ciao
l3on4rdo

Re: [Python] Come spezzettare la tabella dell'esempio

Messaggio da l3on4rdo »

No, aspetta, le righe iniziano tutte allo stesso modo.
Stavo guardando il file per come lo visualizza il forum, ma copiandolo e aprendolo con gedit ho visto che le righe non sono come le avevo intese.
Quindi la faccenda è ancora più semplice.
Ti sto buttando giù un esempio.

Ciao
l3on4rdo

Re: [Python] Come spezzettare la tabella dell'esempio

Messaggio da l3on4rdo »

Io farei una cosa del genere:

Codice: Seleziona tutto

>>> inFile = open('dummy.txt')
>>> for line in inFile:
...     line = line.lstrip()
...     if line[0].isdigit():
...             line = line.split()
...             for index in [3,5,7,10]:
...                     print line[index] + '\t',
...             print 
... 
54983.00	0.031540	0.533564	0.2517073	
54984.00	0.035498	0.533731	0.2503537	
54985.00	0.039516	0.534361	0.2491601	
54986.00	0.043773	0.535228	0.2481804	
54987.00	0.048164	0.536559	0.2474214	
54988.00	0.051763	0.537789	0.2468931	
54989.00	0.055262	0.538788	0.2465087	
54990.00	0.058631	0.539480	0.2462295	
54991.00	0.061698	0.540065	0.2459726	
54992.00	0.064372	0.540441	0.2456633	
54993.00	0.067594	0.540422	0.2452479	
54994.00	0.071060	0.540558	0.2446650	
Ci sono ovviamente da fare delle modifiche per far scrivere l'output direttamente in un file.
Inoltre, per esempio con l'aiuto del modulo argparse, puoi passare come parametri le colonne che vuoi stampare.
Colonne che qui ho indicato come lista, scrivendo:

Codice: Seleziona tutto

for index in [3,5,7,10]:
ciao

ps:
Ho modificato le ultime tre righe del tuo file dummy.txt, perché presumo che hai dimenticato uno spazio.
Ovvero "9 610" l'ho riscritto come "9 6 10" e così via per le altre due righe.
Bakuriu
Entusiasta Emergente
Entusiasta Emergente
Messaggi: 1156
Iscrizione: venerdì 23 ottobre 2009, 23:43
Desktop: KDE4
Distribuzione: Kubuntu 12.04 LTS - x86_64

Re: [Python] Come spezzettare la tabella dell'esempio

Messaggio da Bakuriu »

La mia versione(leggermente più personalizzabile, nel caso volessi cambiare qualcosa):

Codice: Seleziona tutto

LINE_TEMPLATE = '{0}\t{1}\t{2}\t{3}'
INDEXES = (3, 5, 7, 10)

LINE_MATCHER = (lambda line: line.lstrip()[0].isdigit())

def get_fields(fobj, indexes=INDEXES, line_matcher=LINE_MATCHER):
    '''Given a file-like object yields the interesting fields
    for each line.
    '''
    
    for line in fobj:
        if line_matcher(line):
            yield [value for i,value in enumerate(line.split())
                         if i in indexes]


def print_fields(fobj, indexes=INDEXES, line_matcher=LINE_MATCHER):
    '''Given a file-like object prints the interesting fields
    for each line.
    '''
    
    for fields in get_fields(fobj, indexes, line_matcher):
        print LINE_TEMPLATE.format(*fields)


if __name__ == '__main__':
    import sys
    print_fields(open(sys.argv[1]))
Se volessi cambiare le colonne da scegliere basta che cambi la costante INDEXES, se vuoi cambiare la formattazione cambia LINE_TEMPLATE, se invece vuoi un altro criterio per la scelta delle righe cambia LINE_MATCHER.
Avatar utente
BlueEyes
Entusiasta Emergente
Entusiasta Emergente
Messaggi: 1330
Iscrizione: giovedì 15 marzo 2012, 14:08

Re: [Python] Come spezzettare la tabella dell'esempio

Messaggio da BlueEyes »

Vi ringrazio, delle risposte rapide e, per maggior comprensione, passo il link del mega-file originario, in cui c'è la risposta a questo ps: Ho modificato le ultime tre righe del tuo file dummy.txt, perché presumo che hai dimenticato uno spazio, ovvero alcuni spazi sono riempiti e altri no, in funzione del format della data. C'è un altro particolare, che per ora tralasciamo, il big-file verso la fine delle righe non ha le colonne al completo, ma in linea di principio non mi interessa, perché sono righe in più che si possono eliminare con un normale editor.
Comincerò le prime prove più tardi, e poi riferirò qui. Thanks a lot.
l3on4rdo

Re: [Python] Come spezzettare la tabella dell'esempio

Messaggio da l3on4rdo »

Indubbiamente meglio l'esempio di Bakuriu.
Disco solo una cosa, in merito alla personalizzazione delle colonne.
Io lo farei con argparse, in questo modo:

Codice: Seleziona tutto

#! /usr/bin/env python
# -* coding: iso-8859-15 -*-

import argparse

parser = argparse.ArgumentParser()
parser.add_argument('-c', '--columns', nargs='+', type=int, action="store")

arguments = parser.parse_args()

print arguments.columns
Puoi lanciare senza nessun parametro, ottenenedo None, ovvero:

Codice: Seleziona tutto

l3on4rdo@l3on4rdo-laptop:~/Scrivania$ ./sceltaColonne.py 
None
oppure con i numeri delle colonne che vuoi stampare (considerando che partono da 0, oppure facendo gli opportuni "ritocchi" per far partire la numerazione delle colonne da 1):

Codice: Seleziona tutto

l3on4rdo@l3on4rdo-laptop:~/Scrivania$ ./sceltaColonne.py --columns 3 5 7 10
[3, 5, 7, 10]
In questo secondo modo, hai direttamente la lista con le colonne che ti interessano.

Puoi pertanto usare la lista (anche se sullo script di Bakuriu è una tupla) di default se arguments.columns è None.
Altrimenti usi la lista di colonne che passi, senza andare a modificare il codice dello script, di volta in volta.

Mi pare che argparse sia disponibile di default con python a partire dalla 3.2
Se non lo hai, lo puoi scaricare da qui
Avatar utente
BlueEyes
Entusiasta Emergente
Entusiasta Emergente
Messaggi: 1330
Iscrizione: giovedì 15 marzo 2012, 14:08

Re: [Python] Come spezzettare la tabella dell'esempio

Messaggio da BlueEyes »

Sì, Leonardo, l'argparse ce l'ha pure la versione installata sul mio pc (Ubuntu 11.04). Ecco l'output:

Codice: Seleziona tutto

$ python
Python 2.7.1+ (r271:86832, Apr 11 2011, 18:05:24) 
[GCC 4.5.2] on linux2
Type "help", "copyright", "credits" or "license" for more information.
>>> import argparse
>>> quit()
Ciao
l3on4rdo

Re: [Python] Come spezzettare la tabella dell'esempio

Messaggio da l3on4rdo »

Dovresti comunque chiarire quando dici: "ovvero alcuni spazi sono riempiti e altri no, in funzione del format della data."
E anche in che senso alla fine non si hanno colonne al completo.

ciao
Avatar utente
BlueEyes
Entusiasta Emergente
Entusiasta Emergente
Messaggi: 1330
Iscrizione: giovedì 15 marzo 2012, 14:08

Re: [Python] Come spezzettare la tabella dell'esempio

Messaggio da BlueEyes »

l3on4rdo ha scritto:Dovresti comunque chiarire quando dici: "ovvero alcuni spazi sono riempiti e altri no, in funzione del format della data."
E anche in che senso alla fine non si hanno colonne al completo.
Certamente. Ecco alcune righe della tabella:

Codice: Seleziona tutto

12 7 6 56114.00 P  0.111556 0.006439  0.388383 0.008033  P 0.4251709 0.0064093                 P   -74.990     .600   -12.222     .600                                                     
12 7 7 56115.00 P  0.112990 0.006496  0.387793 0.008123  P 0.4250471 0.0064917                 P   -75.015     .600   -12.287     .600                                                     
12 7 8 56116.00 P  0.114407 0.006553  0.387180 0.008213  P 0.4248871 0.0065737                 P   -75.490     .600   -12.365     .600                                                     
12 7 9 56117.00 P  0.115809 0.006609  0.386545 0.008302  P 0.4247509 0.0066554                 P   -76.204     .600   -12.411     .600                                                     
12 710 56118.00 P  0.117194 0.006665  0.385888 0.008391  P 0.4246868 0.0067368                 P   -76.725     .600   -12.448     .600                                                     
12 711 56119.00 P  0.118562 0.006721  0.385209 0.008480  P 0.4247279 0.0068177                 P   -76.897     .600   -12.469     .600                                                     
12 712 56120.00 P  0.119912 0.006776  0.384508 0.008568  P 0.4248887 0.0068984                 P   -76.963     .600   -12.441     .600                                                     
12 713 56121.00 P  0.121244 0.006832  0.383787 0.008656  P 0.4251683 0.0069788                 P   -77.184     .600   -12.390     .600                                                     
12 714 56122.00 P  0.122558 0.006886  0.383044 0.008744  P 0.4255519 0.0070588                 P   -77.529     .600   -12.399     .600                                                     
12 715 56123.00 P  0.123853 0.006941  0.382281 0.008831  P 0.4260083 0.0071385                 P   -77.813     .600   -12.496     .600                                                     
12 716 56124.00 P  0.125129 0.006995  0.381497 0.008918  P 0.4264934 0.0072179                 P   -77.964     .600   -12.604     .600                                                     
12 717 56125.00 P  0.126385 0.007048  0.380694 0.009005  P 0.4269541 0.0072970                 P   -78.015     .600   -12.636     .600                                                     
12 718 56126.00 P  0.127621 0.007102  0.379871 0.009091  P 0.4273365 0.0073758                 P   -77.965     .600   -12.593     .600                                                     
12 719 56127.00 P  0.128837 0.007155  0.379029 0.009177  P 0.4275968 0.0074544                 P   -77.821     .600   -12.53
......................................................................................................................................
......................................................................................................................................
13 5 6 56418.00 P  0.097643 0.017451  0.394694 0.028304  P 0.1343568 0.0251504                                                                                                             
13 5 7 56419.00 P  0.099303 0.017479  0.394607 0.028359  P 0.1326124 0.0252023                                                                                                             
13 5 8 56420.00 P  0.100966 0.017505  0.394493 0.028414  P 0.1310318 0.0252542                                                                                                             
13 5 9 56421.00 P  0.102631 0.017532  0.394352 0.028470  P 0.1296020 0.0253060                                                                                                             
13 510 56422.00 P  0.104297 0.017559  0.394184 0.028525  P 0.1284343 0.0253578                                                                                                             
13 511 56423.00 P  0.105964 0.017586  0.393989 0.028580  P 0.1274611 0.0254096                                                                                                             
13 512 56424.00                                                                                                                                                                            
13 513 56425.00                                                                                                                                                                            
13 514 56426.00                                                                                                                                                                            
13 515 56427.00                                                                                                                                                                            
13 516 56428.00                                                                                                                                                                            
13 517 56429.00                                                                                                                                                                            
13 518 56430.00              
I primi 3 campi (anno,mese,giorno) non sempre sono separati da uno spazio, da ottobre a dicembre e da giorno 10 in poi non c'è alcuno spazio, la stringa è unica (121028) oppure ce n'è uno solo (12 915) per i mesi 1-9.
Verso le ultime righe la tabella non ha tutti i campi occupati, per cui potrebbe accadere che l'algoritmo da lì in avanti si blocchi. Non lo so a-priori: se mi segnala errore e la parte precedente non viene visualizzata/stampata, il problema esiste e si deve rimediare eliminando le ultime righe prima di attivare python; se invece esso va oltre mostrando qualsiasi output, non c'è problema, il residuo del file finale si può eliminare dopo.
In altre parole: è strettamente necessario che la tabella data sia a numero di campi costanti dalla prima all'ultima riga?
Beh, lo vedrò appena seguirò i primi test e poi riferirò. Ciao
l3on4rdo

Re: [Python] Come spezzettare la tabella dell'esempio

Messaggio da l3on4rdo »

Le righe con un numero minore di campi, le gestisci o controllando quanti sono prima di fare qualcosa, oppure con una try/except
La questione relativa alle dati, mi sa, è un po' più complessa e andrebbe "riflettuta". Non hai modo di stampare le date sempre nello stesso formato? (due cifre per l'anno, due per il mese e due per il giorno, separate da uno spazio)
Avatar utente
BlueEyes
Entusiasta Emergente
Entusiasta Emergente
Messaggi: 1330
Iscrizione: giovedì 15 marzo 2012, 14:08

Re: [Python] Come spezzettare la tabella dell'esempio

Messaggio da BlueEyes »

l3on4rdo ha scritto:La questione relativa alle dati, mi sa, è un po' più complessa e andrebbe "riflettuta". Non hai modo di stampare le date sempre nello stesso formato? (due cifre per l'anno, due per il mese e due per il giorno, separate da uno spazio)
Sì, lo farò con vim, spazzolando le prime 6 colonne ed imponendo che gli spazi vuoti diventino zeri, solo che ... si perderebbe di colpo l'immediatezza dell'algoritmo: risolve il problema, a condizione che sia effettuato questo passaggio preliminare con altro software.
Ciao, e ancora grazie.
l3on4rdo

Re: [Python] Come spezzettare la tabella dell'esempio

Messaggio da l3on4rdo »

L'immediatezza dell'algoritmo deve andare incontro ad una progettazione oculata a priori.
O esiste un metodo per capire come sono scritte le date, oppure devi cambiare il modo in cui le stampi e renderlo in un certo senso ricorrente.

ciao
Avatar utente
BlueEyes
Entusiasta Emergente
Entusiasta Emergente
Messaggi: 1330
Iscrizione: giovedì 15 marzo 2012, 14:08

Re: [Python] Come spezzettare la tabella dell'esempio

Messaggio da BlueEyes »

l3on4rdo ha scritto:L'immediatezza dell'algoritmo deve andare incontro ad una progettazione oculata a priori.
O esiste un metodo per capire come sono scritte le date, oppure devi cambiare il modo in cui le stampi e renderlo in un certo senso ricorrente.
Francamente, non capisco ... cosa c'è da capire: le date si susseguono come quelle del calendario, giorno dopo giorno, solo che l'IERS (cfr. un link precedente) pubblica così quella tabella, senza 'leading zero' per definire la data nei 'buchi' a due cifre.

La faccenda della progettazione oculata a priori mi sfugge, perché io, aprendo questo topic, ho intenzione di verificare se esiste un modo migliore (attraverso python, che ho cominciato ad apprezzare) di eseguire l'operazione di spezzettamento di quella tabella, che normalmente eseguo con vim.

Scusami se posso esserti sembrato brusco, ma ho voluto precisare ulteriormente.
Ciao
Avatar utente
crap0101
Rampante Reduce
Rampante Reduce
Messaggi: 8242
Iscrizione: martedì 30 ottobre 2007, 6:33
Desktop: LXDE
Distribuzione: Ubuntu 18.04.1 LTS
Sesso: Maschile
Località: TO
Contatti:

Re: [Python] Come spezzettare la tabella dell'esempio

Messaggio da crap0101 »

in questo caso lo split per campi non può essere la prima cosa da fare.
Potresti usare una regex, nel caso ti serva identificare anche la data ma, in questo caso, in cui ti interessano solo le colonne successive e sftruttando il fatto che le prime tre colonne della data - comunque formattate - occupano sempre i primi 6 caratteri della linea, ti basta 'tagliare' quella prima parte, o facendolo prima di tutto oppure - prendendo l'esempio di Bakuriu - aggiungendo un parametro skip=n alla funzione che ti yielda i risultati, con *n* che indica il numero di caratteri da skippare all'inizio di ogni linea.
http://www.gnu.org/ http://boinc.berkeley.edu/ http://www.python-it.org/
- Ricorda le ultime parole di suo padre: «Sta' alla larga dalle chiese, figlio. La sola cosa per cui hanno la chiave è il merdaio. E giurami che non porterai mai un distintivo della legge» - W.S. Burroughs
l3on4rdo

Re: [Python] Come spezzettare la tabella dell'esempio

Messaggio da l3on4rdo »

No, no, tranquillo. Non sei sembrato brusco... lo sei proprio stato :D
Scherzi a parte, non avevo capito (quindi errore mio) che tu prendi questi dati da una fonte che non controlli.
Per questo ti dicevo che ti conveniva modificare a monte.
Il suggerimento di crap0101, unito a quello di Bakuriu, però, risolve la cosa.

Ciao
Avatar utente
BlueEyes
Entusiasta Emergente
Entusiasta Emergente
Messaggi: 1330
Iscrizione: giovedì 15 marzo 2012, 14:08

Re: [Python] Come spezzettare la tabella dell'esempio

Messaggio da BlueEyes »

Ci proverò, ragazzi! So che al primo intoppo troverò dei validi aiuti. E' questo il bello del forum!
A presto
Avatar utente
BlueEyes
Entusiasta Emergente
Entusiasta Emergente
Messaggi: 1330
Iscrizione: giovedì 15 marzo 2012, 14:08

Re: [Python] Come spezzettare la tabella dell'esempio

Messaggio da BlueEyes »

Soluzione semplificata (... con errore).
Ho chiamato il dbase di riferimento dummy4.txt, e ne ho coperto gli spazi vuoti dei primi sei caratteri con dei punti esclamativi, in modo da poterli raggruppare in un'unica stringa. Eccolo:

Codice: Seleziona tutto

12!7!8 56116.00 P  0.114407 0.006553  0.387180 0.008213  P 0.4248871 0.0065737                 P   -75.490     .600   -12.365     .600
12!7!9 56117.00 P  0.115809 0.006609  0.386545 0.008302  P 0.4247509 0.0066554                 P   -76.204     .600   -12.411     .600
12!710 56118.00 P  0.117194 0.006665  0.385888 0.008391  P 0.4246868 0.0067368                 P   -76.725     .600   -12.448     .600
12!711 56119.00 P  0.118562 0.006721  0.385209 0.008480  P 0.4247279 0.0068177                 P   -76.897     .600   -12.469     .600
12!712 56120.00 P  0.119912 0.006776  0.384508 0.008568  P 0.4248887 0.0068984                 P   -76.963     .600   -12.441     .600
12!713 56121.00 P  0.121244 0.006832  0.383787 0.008656  P 0.4251683 0.0069788                 P   -77.184     .600   -12.390     .600
12!714 56122.00 P  0.122558 0.006886  0.383044 0.008744  P 0.4255519 0.0070588                 P   -77.529     .600   -12.399     .600
12!715 56123.00 P  0.123853 0.006941  0.382281 0.008831  P 0.4260083 0.0071385                 P   -77.813     .600   -12.496     .600
12!716 56124.00 P  0.125129 0.006995  0.381497 0.008918  P 0.4264934 0.0072179                 P   -77.964     .600   -12.604     .600
12!717 56125.00 P  0.126385 0.007048  0.380694 0.009005  P 0.4269541 0.0072970                 P   -78.015     .600   -12.636     .600
12!718 56126.00 P  0.127621 0.007102  0.379871 0.009091  P 0.4273365 0.0073758                 P   -77.965     .600   -12.593     .600
12!719 56127.00 P  0.128837 0.007155  0.379029 0.009177  P 0.4275968 0.0074544                 P   -77.821     .600   -12.533     .600
13!5!6 56418.00 P  0.097643 0.017451  0.394694 0.028304  P 0.1343568 0.0251504
13!5!7 56419.00 P  0.099303 0.017479  0.394607 0.028359  P 0.1326124 0.0252023
13!5!8 56420.00 P  0.100966 0.017505  0.394493 0.028414  P 0.1310318 0.0252542
13!5!9 56421.00 P  0.102631 0.017532  0.394352 0.028470  P 0.1296020 0.0253060
13!510 56422.00 P  0.104297 0.017559  0.394184 0.028525  P 0.1284343 0.0253578
13!511 56423.00 P  0.105964 0.017586  0.393989 0.028580  P 0.1274611 0.0254096
13!512 56424.00
13!513 56425.00
13!514 56426.00
13!515 56427.00
13!516 56428.00
13!517 56429.00
13!518 56430.00
Il corrispondente codice python è il seguente:

Codice: Seleziona tutto

# ------------ odd.py ----------------
#
LINE_TEMPLATE = '{0}\t{1}\t{2}\t{3}'
INDEXES = (1, 3, 5, 8)

LINE_MATCHER = (lambda line: line.lstrip()[0].isdigit())

def get_fields(fobj, indexes=INDEXES, line_matcher=LINE_MATCHER):
    '''Given a file-like object yields the interesting fields
    for each line.
    '''
       
    for line in fobj:
        if line_matcher(line):
            yield [value for i,value in enumerate(line.split())
                         if i in indexes]


def print_fields(fobj, indexes=INDEXES, line_matcher=LINE_MATCHER):
    '''Given a file-like object prints the interesting fields
    for each line.
    '''
       
    for fields in get_fields(fobj, indexes, line_matcher):
            print LINE_TEMPLATE.format(*fields)


if __name__ == '__main__':
    import sys
    print_fields(open(sys.argv[1]))

fobj = open('dummy4.txt', 'rb')
outfile = open('risu.txt', 'w+')
outfile.write(str("Tabella originaria ridotta a 4 colonne") + '\n\n')

get_fields(fobj)
print_fields(fobj)

outfile.print_fields(fobj)   # non stampa nulla sul file, a causa dell'errore nel tuple
outfile.close()
fobj.close()

'''
Se volessi cambiare le colonne da scegliere basta che cambi la costante 
INDEXES, se vuoi cambiare la formattazione cambia LINE_TEMPLATE, 
se invece vuoi un altro criterio per la scelta delle righe cambia 
LINE_MATCHER.
--------
oppure - prendendo l'esempio di Bakuriu - aggiungendo un parametro skip=n 
alla funzione che ti yielda i risultati, con *n* che indica il numero di 
caratteri da skippare all'inizio di ogni linea.
'''
Ed ecco il risultato:

Codice: Seleziona tutto

>>> import odd
56116.00        0.114407        0.387180        0.4248871
56117.00        0.115809        0.386545        0.4247509
56118.00        0.117194        0.385888        0.4246868
56119.00        0.118562        0.385209        0.4247279
56120.00        0.119912        0.384508        0.4248887
56121.00        0.121244        0.383787        0.4251683
56122.00        0.122558        0.383044        0.4255519
56123.00        0.123853        0.382281        0.4260083
56124.00        0.125129        0.381497        0.4264934
56125.00        0.126385        0.380694        0.4269541
56126.00        0.127621        0.379871        0.4273365
56127.00        0.128837        0.379029        0.4275968
56418.00        0.097643        0.394694        0.1343568
56419.00        0.099303        0.394607        0.1326124
56420.00        0.100966        0.394493        0.1310318
56421.00        0.102631        0.394352        0.1296020
56422.00        0.104297        0.394184        0.1284343
56423.00        0.105964        0.393989        0.1274611
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
  File "odd.py", line 35, in <module>
    print_fields(fobj)
  File "odd.py", line 23, in print_fields
    print LINE_TEMPLATE.format(*fields)
IndexError: tuple index out of range
>>> quit()
A causa dell'errore nella lettura della tabella con dati incompleti, il file risu.txt rimane questo:

Codice: Seleziona tutto

Tabella originaria ridotta a 4 colonne
Riepilogando, in questo primo approccio mi serve aiuto per superare l'impasse delle lettura finale del dbase.
Ciao
Avatar utente
crap0101
Rampante Reduce
Rampante Reduce
Messaggi: 8242
Iscrizione: martedì 30 ottobre 2007, 6:33
Desktop: LXDE
Distribuzione: Ubuntu 18.04.1 LTS
Sesso: Maschile
Località: TO
Contatti:

Re: [Python] Come spezzettare la tabella dell'esempio

Messaggio da crap0101 »

io consigliavo una cosa diversa, per evitare di dover modificare il file:

Codice: Seleziona tutto

def skip_fst (n):
    if n == 0:
        return lambda line:line
    else:
        return lambda line: line[n:]

def get_fields(fobj, indexes=INDEXES, line_matcher=LINE_MATCHER, skip=0):
        '''Given a file-like object yields the interesting fields
        for each line.
        '''
        fskip = skip_fst(skip)
        for line in fobj:
            if line_matcher(line):
                yield [value for i,value in enumerate(fskip(line).split())
                             if i in indexes]
per cui

Codice: Seleziona tutto

>>> import StringIO
>>> c = StringIO.StringIO()
>>> for x in range(5):
>>> for x in range(5):  c.write("%d line %d l k j h g y t 6 8 o\n" % (x,x))
... 
>>> c.read()
'0 line 0 l k j h g y t 6 8 o\n1 line 1 l k j h g y t 6 8 o\n2 line 2 l k j h g y t 6 8 o\n3 line 3 l k j h g y t 6 8 o\n4 line 4 l k j h g y t 6 8 o\ng y t 6 8 o\nline 1 l k j h g y t 6 8 o\nline 2 l k j h g y t 6 8 o\nline 3 l k j h g y t 6 8 o\nline 4 l k j h g y t 6 8 o\n'
>>> c.seek(0)
>>> for x in get_fields(c): print x
... 
['l', 'j', 'g', '6']
['l', 'j', 'g', '6']
['l', 'j', 'g', '6']
['l', 'j', 'g', '6']
['l', 'j', 'g', '6']
>>> c.seek(0)
>>> for x in get_fields(c,skip=2): print x
... 
['k', 'h', 'y', '8']
['k', 'h', 'y', '8']
['k', 'h', 'y', '8']
['k', 'h', 'y', '8']
['k', 'h', 'y', '8']
>>> 
Riguardo gli errori, dal momento che le righe parzialmente/non correttamente formattate non ti interessano e il programma non deve bloccarsi a causa loro, le gestisci catturando l'eccezione (IndexErroe in questo caso) e semplicemente ignori quelal linea.
http://www.gnu.org/ http://boinc.berkeley.edu/ http://www.python-it.org/
- Ricorda le ultime parole di suo padre: «Sta' alla larga dalle chiese, figlio. La sola cosa per cui hanno la chiave è il merdaio. E giurami che non porterai mai un distintivo della legge» - W.S. Burroughs
Avatar utente
BlueEyes
Entusiasta Emergente
Entusiasta Emergente
Messaggi: 1330
Iscrizione: giovedì 15 marzo 2012, 14:08

Re: [Python] Come spezzettare la tabella dell'esempio

Messaggio da BlueEyes »

Ciao, e grazie per la risposta.
Ho cercato di replicare il tuo codice (per capirne il funzionamento), ma ho trovato l'errore che riporto sotto.

Codice: Seleziona tutto

LINE_MATCHER = (lambda line: line.lstrip()[0].isdigit())
INDEXES = (1, 3, 5, 8)

def skip_fst (n):
    if n == 0:
        return lambda line:line
    else:
        return lambda line: line[n:]

def get_fields(fobj, indexes=INDEXES, line_matcher=LINE_MATCHER, skip=0):
        '''Given a file-like object yields the interesting fields
        for each line.
        '''
        fskip = skip_fst(skip)
        for line in fobj:
            if line_matcher(line):
                yield [value for i,value in enumerate(fskip(line).split())
                             if i in indexes]
Ecco l'output

Codice: Seleziona tutto

>>> import StringIO
>>> c = StringIO.StringIO()
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
AttributeError: 'module' object has no attribute 'StringIO'
>>>
Scrivi risposta

Ritorna a “Programmazione”

Chi c’è in linea

Visualizzano questa sezione: 0 utenti iscritti e 7 ospiti