Caricamento dati da excel con python

mic_1
Ciao a tutti!
Sono alle prime armi con python. Sto provando a caricare e rielaborare dati da file excel.
Non so se faccio bene ma vado a leggere tutte le righe per ogni colonna e le confronto in modo da non riportare doppioni ma cicla solo la prima colonna.
Ho usato sheet.ncols ma nonostante tutto solo la prima colonna viene presa in considerazione.
Il mio file dati era in txt ma le info non erano ordinate per cui ho pensato di riodinarle su excel e poi cercare i dati che mi interessano (sono elenco delle interazioni tra proteine).

Ho creato poi una seconda scheda excel su cui scrivere i risultati della elaborazione ma non sheet.write() non scrive ahimè, per cui per velocizzare ho creato un file txt.

Oltre ad individuare i singoli nodi ho contato pure le interazioni(il grado per ciascun nodo) ma purtroppo non riuscendo a ciclare con il FOR per tutte le colonne non ho potuto distinguere i 4 tipi di interazioni per ciascun nodo.

Mi potreste dare qualche dritta e magari correggermi gli sbagli? Non vorrei perdermi in codice che magari scritto in altro modo è più rapido e di qualità.

Grazie a chiunque mi risponderà!

PS: Una volta elaborati i dati dovrò caricare in matrice le informazioni necessarie per il calcolo statistico.
PS2: Mi viene sovrascitta la riga anzichè riportare le righe una sotto l'altra. Non so come correggere. Potreste aiutarmi? Vorrei caricare qui i file .py e .xlsx Come fare?
Grazie

Risposte
mic_1
Ho provato anche a riordinare il file .txt su excel ma le righe vendono sovrapposte in fase di scrittura sempre sulla prima riga.

apatriarca
Senza informazioni più precise su quello che stai cercando di fare è difficile capire dove tu stia sbagliando. Prova a copiare il tuo codice in un post.

mic_1
RIPORTO QUI IL CODICE. COME POSSO CARICARE IL FILE .TXT?
# mypath should be the complete path for the directory containing the input text files

mypath = 'C:/Users/Michela/Desktop/eserc_python/PROVA_IMPORT/prova1/NetCart'

from os import listdir
from os.path import isfile, join
textfiles = [ join(mypath,f) for f in listdir(mypath) if isfile(join(mypath,f)) and '.txt' in  f]

#import xlwt
import xlrd
from xlwt import Workbook 
from os.path import exists
import time
import os
#import xlsxwriter 

# controllo l'esistenza dei file. Se esistono li elimino
if(exists('generated_xls.xls' and 'log1.txt')):
    os.remove('generated_xls.xls')
    os.remove('log1.txt')
    time.sleep(2)

# apro il file .txt e la riorganizzo in un file .xlsx
for textfile in textfiles:
    f = open(textfile, 'r+', encoding='utf-8')
    row_list = []  
    for string in f:    
        s = string.split()
        t = s[0]
        q = s[1]
        r = s[2]
        str = [t,q,r]
        column_list = zip(str) 

        wb = Workbook()
        sheet = wb.add_sheet('Sheet1')
        sheet2 = wb.add_sheet('Sheet2')
        i=0  
        for column in column_list:
            for item in range(len(column)):       #purtroppo viene sovrascitta la 1a riga         
                sheet.write(item, i, column[item])
            wb.save(join(mypath, 'generated_xls.xls'))
            i+=1         
    f.close()    
     
# Per fare la prova continuo importando manualmente i dati.
# Apro il file .xlsx, leggo le righe controllando che l'argomento non sia lo stesso.
# Questo mi consente di contare il numero dei nodi, il numero di link per ogni nodo.
# Vorrei poter ciclare anche sulla seconda colonna per verificare il numero di
# ciascuna interazione.
wb1 = xlrd.open_workbook('network.xlsx') 
sheet3 = wb1.sheet_by_index(0) 

y = sheet3.ncols
x = sheet3.nrows
fx = open('log1.txt','w+', encoding='utf-8')
for column in range(0,y):
    countLINK = 1
    count_LINK = 1
    for rows in range(0,x):        
        A = sheet3.cell_value(rows,column)
        B = sheet3.cell_value(rows + 1,column)
        C = sheet3.cell_value(rows - 1,column)    
        if (A == B or A == C):  
#            #print("UGUALE = " + str(countLINK) + " " + A)
            countLINK += 1            
            if A != B :
                # vorrei provare a scrivere in una seconda scheda dello stesso file .xlsx 
                #sheet2.write(rows, i, column[rows])
#                print(A, file = fx)                  
                print(A + " = " + str(countLINK - 1), file = fx)
                # fx.write(A + " = " + str(countLINK - 1))
#                fx.write(A + " = " + str(countLINK - 1))
                countLINK = 0           
        else:      
#            print('preso', file = fx)  
#            fx.write(A + " = " + str(count_LINK) + '\n')
#            fx.write(A + " = " + str(count_LINK))
            print(A + " = " + str(count_LINK), file = fx)  
fx.close()

apatriarca
[xdom="apatriarca"]Ho modificato il post in modo da includere il codice tra tag CODE e quindi preservare l'indentazione che è importante per Python.[/xdom]

Nel seguente codice
        i=0 
        for column in column_list:
            for item in range(len(column)):
                sheet.write(item, i, column[item])

la variabile [inline]i[/inline] rimane uguale a zero per tutti i cicli. Suppongo che quello che volessi fare era qualcosa come
        for i, column in enumerate(column_list):
            for item in range(len(column)): 
                sheet.write(item, i, column[item])


Un altro error è nella riga
if(exists('generated_xls.xls' and 'log1.txt')):

Infatti [inline]'generated_xls.xls' and 'log1.txt'[/inline] è uguale a [inline]'log1.txt'[/inline] e stai quindi semplicemente verificando l'esistenza di questo ultimo file. Non mi è inoltre chiaro lo scopo di inserire uno sleep in questo caso.

mic_1
Anche con le modifiche il risultato non cambia:
scrive sempre sulla prima riga, cicla sempre li, quando io vorrei scrivere su tutte le righe il contenuto delle 3 celle.

Nel controllo dell'esistenza file ho inserito AND in modo tale che sia sufficiente che ne esista uno dei due per passare alla fase successiva di rimozione file.

sleep lo avevo messo per rallentare un attimo ma poi lo tolgo.

In sostanza non ho risolto.

apatriarca
In effetti ad una seconda lettura il codice è praticamente tutto sbagliato. Dopo la lettura di ogni riga, apri il file, scrivi la prima riga del file e poi lo chiudi. Credo che il seguente codice faccia quello che desideravi ottenere:
wb = Workbook()
sheet = wb.add_sheet('Sheet1')

row = 0
for textfile in textfiles:
    with open(textfile, 'r+', encoding='utf-8') as f:
        for line in f:   
            items = line.split()
            for col, label in enumerate(items):
                sheet.write(row, col, label=label)
            row += 1
            
wb.save(join(mypath, 'generated_xls.xls'))

mic_1
WOW!! Perfect

si è proprio quello che volevo... ora procedo con la seconda parte, ossia leggo la 1a scheda, elaboro e scrivo il risultato sulla 2a scheda. Domani provo a correggerlo da sola. In caso posto qui per help!

Che tu sappia con PANDAS si può velocizzare ? Grazie

mic_1
Allora.... sto facendo delle prove...mi chiedevo e vi chiedo...

Quando salvo il file, vorrei poi leggerlo, aggiungere una 2a scheda e scrivere su questa.
Per leggerlo devo riaprirlo o posso usare una libreria che mi consente di importare da txt, scrivere su 1a scheda, leggere la 1a scheda, e scrivere sulla 2a???
Perchè con XLRD E XLWT è tutto un apri e salva...o scrivi e salva.
Ho provato con OPENPYXL , dopo aver usato XLWT, ma mi restituisce errore.

apatriarca
Non ho mai lavorato con file excel usando Python. Ma perché stai salvando il file per poi riaprirlo subito dopo quando puoi semplicemente usare i dati che hai appena letto?

mic_1
Non è da molto che uso python, sono ancora alle prime armi.

Ho notato che finchè non salvo il file non lo vedo in cartella.
-prima effettuo una scrittura in fase di importazione (uso la libreria xlwt)
-poi lettura dei dati da manipolare (uso la libreria xlrd)
-infine scrittura dei risultati sulla 2a scheda (uso la libreria xlwt)

Ho cercato e provato più volte anche con altre librerie sperando di trovarne una che mi permettesse di leggere e scrivere senza dover richiamare ogni volta il workbook e la worksheet che serve al momento.

dopo il wb.save(...)
ho caricato il file in lettura con

wb2 = xlrd.open_workbook(join(mypath,'generated_xls.xls'))
sheet_r = wb2.sheet_by_name("Sheet1")

ciclo per le righe e nel punto in cui devo scrivere ho richiamato xlwt e la sheet2 precedentemente creata.

Mi potresti spiegare come procedere in maniera più rapida? Te ne sarei grata.

PS: LE INFORMAZIONI CHE STO ELABORANDO non sono numeriche ma INTERAZIONI TRA PROTEINE che consistono in nome di PROTEINE/NODI e tipi di INTERAZIONE/LINKS. Ho pensato che la cosa più naturale fosse portare tutto su excel e rielaborare le informazioni finchè non trovo il numero dei nodi e per ciascun nodo il numero di interazioni suddividendole se riesco per tipologia di interazione. Solo a questo punto potrei procedere con i calcoli statistici richiesti.
Che ne pensi?

apatriarca
In quale ambiente/linguaggio hai l'intenzione di procedere con i calcoli statistici? Mi sembra infatti che quello che stai cercando di fare in Python possa essere fatto anche direttamente all'interno di Excel. Se l'analisi statistica deve avvenire in Excel allora non vedo la ragione di usare Python.

Se al contrario l'idea è di usare Python per tutto, allora cercare di esportare in Excel è solo una inutile complicazione. Ma se proprio vuoi scrivere dei file Excel, allora puoi forse dare una occhiata a Panda (può in effetti esserti utile in ogni caso..).

mic_1
beh se ci fosse modo di riordinare le informazioni da un file, memorizzarle, elaborarle per il conteggio e salvarle in delle variabili di appoggio per me va bene. L'unica cosa è che non so come si fa :-D :lol:

Devo poi effettuare dei calcoli e applicare la teoria dei grafi :roll: :-D

apatriarca
Perché non inizi a descrivere che cosa vuoi fare con questi dati? Se ho capito bene il tuo input sono diversi file di testo, con ogni riga formata da tre parole separate da spazi. Ogni riga è una interazione tra due proteine di un qualche tipo? Il primo passaggio è quello di memorizzare questi dati in un qualche tipo di struttura dati (per iniziare possiamo supporre una lista probabilmente). Che cosa vuoi fare poi con questi dati esattamente? Posso provare a guidarti a scrivere il codice che ti serve.

mic_1
Ti ringrazio! Ti spiego: ho bisogno di risalire a quale siano i nodi, i links per ogni nodo (e se possibile anche le diverse tipologie di interazioni (in totale ne sono 4 in questo caso ma ne potrebbero essere anche di più) uesta è la mia idea tramite excel ma se ci fosse un modo più rapido ne sarei felice :D
Ho scaricato la libreria Networkx per i calcoli successivi.
Ho notato che alcune link sono diretti altri indiretti, ma per il caso in esame credo si debba ricorrere al SCALE-FREE NETWORK e calcolare le proprietà dei network come coeff di clustering, betweenees, centralità etc...

volevo poi realizzare grafici con matplotlib o pyplot... poi vedo...

Sto provando ora a studiarmi pandas per vedere come manipola le informazioni. Pare sia ottimo per i data science.
Non so però quanto possa essere utile per dati non numerici. Ora cmq provo...

mic_1
Io avevo scritto una parte di codice in cui caricava da .txt in questo modo, usando variabili di appoggio:

for textfile in textfiles:
f = open(textfile, 'r+', encoding='utf-8')
row_list = []
for string in f:
s = string.split()
t = s[0]
q = s[1]
r = s[2]
str = [t,q,r]

str corrisponde alla mia Tupla:
t contiene la prima colonna
q la 2a colonna
r la 3a colonna

A questo punto individuare i nodi e contarli mi risultava difficile, per questo ho pensato di scriverli su excel.

NOTA:
Ho riadattato il codice con numpy creando degli array[] .
C'è modo di confrontare gli elementi di uno stesso array tra loro???

for textfile in textfiles:
f = open(textfile, 'r+', encoding='utf-8')
col0 = []
col1 = []
col2 = []
for string in f:
s = string.split()
col0 = numpy.array(s[0])
col1 = numpy.array(s[1])
col2 = numpy.array(s[2])

se faccio un ciclo for
for i in range(0, len(s)):
c'è modo di confrontare gli elementi di uno stesso array????

GRAZIE

apatriarca
Entrambi i codici hanno lo stesso difetto che aveva il tuo codice originario quando scrivevi i valori nel file excel. Continui infatti a sovrascrivere gli stessi valori. Il seguente codice memorizza tutti i dati in una lista di tuple di 3 elementi:
values = []
for textfile in textfiles:
    with open(textfile, 'r') as f:
        for line in f:
            t, q, r = line.split()
            values.append((t, q, r))

A questo punto [inline]values[0][/inline] sarà ad esempio la prima riga, [inline]values[1][/inline] la seconda e così via.. A seconda di quello che devi fare, altre strutture dati potrebbero essere migliori ovviamente. Per esempio, se volessi raggruppare le righe in base al primo valore puoi salvare tutto in un defaultdict come segue:
values = defaultdict(list)
for textfile in textfiles:
    with open(textfile, 'r') as f:
        for line in f:
            t, q, r = line.split()
            values[t].append((q, r))

In questa versione avresti che [inline]values.keys()[/inline] è la lista di tutti i possibili primi valori (non duplicati) e [inline]values[key][/inline] è la lista di tutte le coppie di valori che seguono [inline]key[/inline] nei files.

mic_1
Ti ringrazio! Ho provato ma mi restituisce errore qui: t, q, r = line.split() (Ho provato ad inserire *r ma nulla)
Ora provo a vedere in giro nel web se ci sono soluzioni in merito.
Alla fine per non perdere tempo mi sono intanto contata manualmente tutti i link entranti per ogni singolo nodo, perchè avevo solo quelli entranti.
per il primo nodo devo contare la prima colonna e così so quanti links uscenti ho. mentre dalla 3a fila risalgo al numero dei nodi entranti.
Dovendo poi ricercare ogni nodo della 1a colonna, nella 3a colonna, non è meglio ricorrere ad excel? o c'è modo di ricorrere a variabili temporanee. Devo ricercare per ogni riga, e non sono poche, per poi contarle.

Secondo te è fattibile senza ricorrere ad excel? e usando quali librerie? così vedo di studiarmele.

Grazie!

apatriarca
Che eccezione viene lanciata? Ci sono delle righe vuote/con solo spazi? Per esempio alla fine del file? Se fosse così devi catturare l'eccezione o aggiungere un test per eliminare quelle righe.

mic_1
Ciao e scusami per il ritardo ma ho fatto alcune prove e ho trovato la soluzione.
Evitando di scrivere su excel ho risolto usando questa istruzione:

node1, edges, node2 = line.strip().split()

Cosa ne pensi???
per ogni singola variabile ottengo l'elenco completo o almeno spero :D

excel mi serviva anche per fare delle verifiche e pensavo di usarlo per archiviare i risultati ma credo sia meglio aprire una finestra per mostrare il grafico e i risultati.

mic_1
Ho notato una cosa...

usando la libreria "Networkx" , i nodes e gli edges risultano essere meno di quelli effettivi presenti su file ...o meglio le mie variabili "node1, node2, edges" li carica tutti mentre usando la libreria alcune interazioni saltano...ad esempio arriva alla "T" per poi saltare all'ultima...
E' vero che in base al tipo di grafo in esame si ha un numero di edge differente...

Ora comq cerco di capire, forse salta quelli esterni in base al grafico...?

Rispondi
Per rispondere a questa discussione devi prima effettuare il login.