2015-12-31 16 views
5

Sto provando a scrivere uno script che scorre su file tramite un determinato pattern/variabile, quindi concatena l'ottava colonna dei file mantenendo le prime 4 colonne comuni a tutti i file . Lo script funziona se uso il seguente comando:concatenate pandas dataframe in un loop di file

reader = csv.reader(open("1isoforms.fpkm_tracking.txt", 'rU'), delimiter='\t') #to read the header names so i can use them as index. all headers for the three files are the same 
header_row = reader.next() # Gets the header 
df1 = pd.read_csv("1isoforms.fpkm_tracking.txt", index_col=header_row[0:4], sep="\t") #file #1 with index as first 5 columns 
df2 = pd.read_csv("2isoforms.fpkm_tracking.txt", index_col=header_row[0:4], sep="\t") #file #2 with index as first 5 columns 
df3 = pd.read_csv("3isoforms.fpkm_tracking.txt", index_col=header_row[0:4], sep="\t") #file #3 with index as first 5 columns 

result = pd.concat([df1.ix[:,4], df2.ix[:,4]], keys=["Header1", "Header2", "Header3"], axis=1) #concatenates the 8th column of the files and changes the header 
result.to_csv("OutputTest.xls", sep="\t") 

Anche se questo funziona, non è pratico per me entrare i nomi dei file uno a uno, come a volte ho 100 di file, tipo quindi non posso in un df .. .funzione per ciascuno. Invece, stavo cercando di usare un ciclo for per fare questo, ma non riuscivo a capirlo. ecco quello che ho finora:

k=0 
for geneFile in glob.glob("*_tracking*"): 
    while k < 3: 
     reader = csv.reader(open(geneFile, 'rU'), delimiter='\t') 
     header_row = reader.next() 
     key = str(k) 
     key = pd.read_csv(geneFile, index_col=header_row[0:1], sep="\t") 
    result = pd.concat([key[:,5]], axis=1) 
    result.to_csv("test2.xls", sep="\t") 

Tuttavia, questo non funziona.

I problemi che sto affrontando sono i seguenti:

  1. Come posso essere in grado di iterare su file di input e generare differenti nomi di variabili per ciascuno che posso poi lo hanno utilizzato nel pd. funzione concat uno dopo l'altro?

  2. Come posso usare un ciclo for per generare un nome di file stringa che è una combinazione di df e un intero

  3. Come posso risolvere lo script precedente ottenere la mia voce desiderata.

  4. Un problema minore riguarda il modo in cui utilizzo la funzione col_index: esiste un modo per utilizzare la colonna # anziché i nomi di colonna? So che funziona per index_col=0 o qualsiasi singolo #. Ma non potrei usare interi per> 1 colonna di indicizzazione.

Si noti che tutti i file hanno la stessa identica struttura e le colonne di indice sono uguali.

Il tuo feedback è molto apprezzato.

+0

Hi @bioprogram, benvenuto a SO. Ottima domanda Attenzione però alla formattazione. La chiarezza è molto importante ... :) Buon anno –

+0

Se ti interessa solo la prima 4 e l'8 colonna, passa semplicemente una lista delle posizioni ordinali: 'pd.read_csv (geneFile, index_col = header_row [0: 1], sep = "\ t", usecols = [0,1,2,3,7]) 'anche io penso che se il campo indice è sempre il primo 2 cols allora puoi semplicemente passarlo ogni volta:' pd. read_csv (geneFile, index_col = [0,1], sep = "\ t", usecols = [0,1,2,3,7]) ' – EdChum

+0

Inoltre non hai bisogno di nominare le variabili, cosa vuoi fare è solo aggiungere ogni df ad una lista e poi alla fine concat tutto il dfs nella lista – EdChum

risposta

1

considerare l'utilizzo di merge con right_index e left_index argomenti:

import pandas as pd 

numberoffiles = 100 

# FIRST IMPORT (CREATE RESULT DATA FRAME) 
result = pd.read_csv("1isoforms.fpkm_tracking.txt", sep="\t", 
         index_col=[0,1,2,3], usecols=[0,1,2,3,7]) 

# ALL OTHER IMPORTS (MERGE TO RESULT DATA FRAME, 8TH COLUMN SUFFIXED ITERATIVELY) 
for i in range(2,numberoffiles+1):  
    df = pd.read_csv("{}isoforms.fpkm_tracking.txt".format(i), sep="\t", 
        index_col=[0,1,2,3], usecols=[0,1,2,3,7]) 

    result = pd.merge(result, df, right_index=True, left_index=True, suffixes=[i-1, i]) 

result.to_excel("Output.xlsx") 
result.to_csv("Output.csv") 
+0

Grazie. Questo funziona. Ma, qui ci sono alcune cose che mi hanno colpito. In realtà, volevo saltare le colonne 2 e 3 dall'output. Così ho scritto: result = pd.read_csv ("1isoforms.fpkm_tracking.txt", sep = "\ t", index_col = [0,3], usecols = [0,3,7]) - Tuttavia, ciò ha dato un errore per quanto riguarda "l'indice di lista fuori range" che mi ha sorpreso, come quando ho messo gli usecols 0,1,2,3,7, funziona. Secondo, suppongo che {} e format (i) significano che in ogni ciclo, sostituisce {} con i, corretto? Quando si imposta l'indice destro e sinistro come TRUE, significa che si unirà solo se tutti gli indici sono uguali? – BioProgram

+0

Inoltre, davvero non capisco cosa fanno i suffissi.L'ho letto sul sito web della riga di comando di panda e ho provato alcuni esempi, ma non aveva senso. Puoi spiegarlo brevemente? – BioProgram

+0

Sì alle tue precedenti due domande. Se cambi 'index_col' assicurati di farlo in entrambe le funzioni' pd.read_csv() '. I suffissi qui impostati in pratica ripetono: col1, col2, col3, ... col100. Io uso la variabile 'i' del ciclo for per farlo. – Parfait