2015-11-03 11 views
5

Spero che questo non è banale, ma mi chiedo quanto segue:Leggere in tutti i file csv da una directory con Python

Se ho una cartella specifica con ncsv file, come potrei iterativo letto tutti loro, uno alla volta, ed eseguono alcuni calcoli sui loro valori?

per un singolo file, per esempio, faccio qualcosa di simile ed eseguire alcuni calcoli sul x array:

import csv 
import os 

directoryPath=raw_input('Directory path for native csv file: ') 
csvfile = numpy.genfromtxt(directoryPath, delimiter=",") 
x=csvfile[:,2] #Creates the array that will undergo a set of calculations 

So che posso verificare quante csv file ci sono in una determinata cartella (controllare here):

import glob 
for files in glob.glob("*.csv"): 
    print files 

Ma non sono riuscito a capire come eventualmente nido la funzione numpy.genfromtxt() in un ciclo for, in modo che ho letto in tutti i file CSV di una directory che spetta a me di speci fy.

EDIT

La cartella ho ha solo jpg e csv file. Questi ultimi sono denominati eventX.csv, dove X varia da 1 a 50. Il ciclo for a cui mi riferisco dovrebbe pertanto considerare i nomi dei file come sono.

risposta

7

Ecco come lo farei:

import os 

directory = os.path.join("c:\\","path") 
for root,dirs,files in os.walk(directory): 
    for file in files: 
     if file.endswith(".csv"): 
      f=open(file, 'r') 
      # perform calculation 
      f.close() 
+0

La riga 'f.close()' può essere posizionata subito dopo aver definito 'x = csvfile [:, 2]'? Il numero '2' è solo esemplificativo. – FaCoffee

+0

E, se posso aggiungere, il tuo codice controlla tutti i file 'csv' in TUTTE le cartelle all'interno di' directory'? – FaCoffee

+1

come nota, il modo consigliato di aprire i file è 'con open (file) come file' questo ha il vantaggio di chiudersi automaticamente quando fuori dal campo di applicazione – Busturdust

3

Credo che si cerca qualcosa di simile

import glob 

for file_name in glob.glob(directoryPath+'*.csv'): 
    x = np.genfromtxt(file_name,delimiter=',')[:,2] 
    # do your calculations 

Modifica

Se si desidera ottenere tutti i csv i file da una cartella (inclusa la sottocartella) è possibile utilizzare subprocess anziché glob (notare che questo codice funziona solo su sistemi linux)

import subprocess 
file_list = subprocess.check_output(['find',directoryPath,'-name','*.csv']).split('\n')[:-1] 

for i,file_name in enumerate(file_list): 
    x = np.genfromtxt(file_name,delimiter=',')[:,2] 
    # do your calculations 
    # now you can use i as an index 

esegue la ricerca prima la cartella e sottocartelle per tutti file_names utilizzando il comando find dal guscio e si applica i calcoli dopo.

+0

Beh, mi piace molto questa soluzione pratica e corta, ma l'ho testata e non ha prodotto ciò che volevo. Ho creato una nuova cartella vuota, ho inserito tre file 'csv' in esso chiamati' file_1.csv', 'file_2.csv' e' file_3.csv', ognuno dei quali ha il valore '1',' 2', e '3' come valore univoco (senza intestazione). Quindi ho creato 'a = numpy.zeros (3)' per riempirlo con quei valori, ma ottengo 'a = ([0,0,0])'. Nel ciclo 'for', i nuovi valori di' a' sono assegnati in questo modo: 'a [file_name] = numpy.genfromtxt (file_name, delimitatore = ',') [0,0]'. Invece di 'a = ([1,2,3])' Ottengo 'a = ([0,0,0])'. – FaCoffee

+1

Hmm ... ha funzionato per i miei semplici esempi ... fammi controllare cosa potrebbe andare storto ... – plonser

+0

@FrancescoCastellani: 'file_name' è una stringa nel mio codice ... cosa intendi con' a [file_name] '? 'a [...]' richiede un numero intero ... non ci sono errori? – plonser

2

Secondo la documentation di numpy.genfromtxt(), il primo argomento può essere un

file, nome file, o generatore di leggere.

Ciò significherebbe che si potrebbe scrivere un generatore che produce le linee di tutti i file di questo tipo:

def csv_merge_generator(pattern): 
    for file in glob.glob(pattern): 
     for line in file: 
      yield line 

# then using it like this 

numpy.genfromtxt(csv_merge_generator('*.csv')) 

dovrebbe funzionare. (Non ho installato numpy, quindi non posso testare facilmente)

+0

L'ultima riga sarà annidata in un ciclo 'for'? – FaCoffee

+1

nonono, è passato nel generatore e come tale ottiene tutti i file – Ward

Problemi correlati