2017-06-16 2 views
1

J'ai un dossier de fichiers CSV que je dois transformer et manipuler/nettoyer, en produisant une base de données avec laquelle je peux continuer à travailler . Je voudrais un fichier de données unique par fichier CSV que j'ai. J'ai écrit le code pour pouvoir manipuler juste l'un des fichiers csv comme je le voudrais, avec une base de données propre à la fin, mais je me suis fait trébucher en essayant de parcourir le dossier et de transformer tous les fichiers. les fichiers csv, se terminant par une trame de données par csv.Transformez un dossier de fichiers CSV de la même manière, puis affichez plusieurs fichiers de données avec python

Voici le code que je travaille avec:

import pandas as pd 
import numpy as np 
import os 
from os import listdir 
import glob 
import win32com.client 

filepath = 'C:/Users/me/BMI' 

xl = win32com.client.gencache.EnsureDispatch('Excel.Application') 

for f in glob.glob(filepath+'/*.xls'): 
    fullname = os.path.abspath(f) 
    xl.Workbooks.Open(fullname) 
    xl.ActiveWorkbook.SaveAs(Filename=fullname.replace('.xls','.csv'), 
     FileFormat=win32com.client.constants.xlCSVMSDOS, 
     CreateBackup=False) 
    xl.ActiveWorkbook.Close(SaveChanges=False) 

os.listdir('C:/Users/me/BMI') 

def find_csv_filenames(path_to_dir, suffix=".csv"): 
    filenames = listdir(path_to_dir) 
    return [ filename for filename in filenames if filename.endswith(suffix) ] 

filenames = list(find_csv_filenames(filepath)) 

for i in filenaames: 
    df = pd.read_csv(filepath+'/'+i) 
    del df['Unnamed: 0'] 

# Extract by rows - create list of rows that are blank 
nul_rows = list(df[df.isnull().all(axis=1)].index) 

list_of_dataframes = [] 
list_of_dataframes.append(df.iloc[:nul_rows[0] - 1,:]) 
for i in range(len(nul_rows) - 1): 
    list_of_dataframes.append(df.iloc[nul_rows[i]+1:nul_rows[i],:]) 

list_of_dataframes.append(df.iloc[nul_rows[4] - 1::]) 

# Remove null columns 
cleaned_tables = [] 
for _df in list_of_dataframes: 
    cleaned_tables.append(_df.dropna(axis=1, how='all')) 

# cleaned_tables is a list of the dataframes 
print(cleaned_tables[0]) 

# drop second row of data frame (subtitle) 
df = df.drop(df.index[0]) 

#set up headers in row 1 
df=df.set_value(1, df.columns[0], 'brands') 

# change column names to proper headers (brand as first column, years of data following) 
for i in list(range(len(df.columns))): 
    df = df.rename(columns={df.columns[i]: df.iloc[0][df.columns[i]]}) 

#get rid of double headers (row 1) 
df = df.drop(df.index[0]) 
+0

Lorsque vous dites que vous êtes victime d'une erreur, obtenez-vous une erreur? – ToothlessRebel

+0

Bonne question, désolé je n'ai pas spécifié, je veux dire que je ne sais pas comment faire de ce script en un seul que je peux traverser et transformer de nombreux fichiers CSV avec, au lieu d'un seul. Jarad a fourni une excellente suggestion dans un autre commentaire sur la façon d'accomplir cela, mais maintenant je suis confronté à des problèmes d'encodage avec la partie pd.read_csv du script. – triciascully

Répondre

1

Si vous avez du code qui transforme un seul .csv et vous souhaitez effectuer les mêmes actions sur tous .csvs dans un répertoire, et à la fin avec un DataFrame unique pour chaque .csv, pourriez-vous faire quelque chose comme ça?

import pandas as pd 
import numpy as np 
import os 

filepath = r'C:\Users\me\BMI' 

df_list = [] 
for file in os.listdir(): 
    if file.endswith('.csv'): 
    temp_df = pd.read_csv(os.path.join(filepath, file), encoding='utf-8') 
    # transformation and clean-up steps here... 

    # ... 
    df_list.append(temp_df) 

Chaque temp_df serait stocké dans le df_list.

Vous pouvez les concaténer en un seul dataframe final à la fin comme celui-ci:

one_df = pd.concat(df_list, ignore_index=True) 

Si vous rencontrez des problèmes de lecture du fichier dans la trame de données, essayez de définir le séparateur sep (si vos données ne sont pas par des virgules délimité) et encoding si vos fichiers csv sont encodés dans un encodage spécifique. Ex:

pd.read_csv(..., sep='\t', encoding='cp1252') 
+0

Merci, Jarad! J'ai essayé de le formater comme vous l'avez dit, mais quand j'imprime (df_list) je reçois []: – triciascully

+0

Je reçois une erreur sur la partie os.listdir (fichier), et je pensais que c'était peut-être parce que le nom de fichier n'est pas le nom de fichier absolu, mais cela ne semble pas non plus être le problème: 3 df_list = [] ----> 4 pour le fichier dans os.listdir (fichier): 5 si file.endswith ('. csv') : 6 temp_df = pd.read_csv (chemin du fichier + '/' + fichier) FileNotFoundError: [WinError 3] Le système ne peut pas trouver le chemin spécifié: 'File_a.csv' – triciascully

+0

J'ai mis à jour le code ci-dessus. Que faire si vous ajoutez ci-dessus 'filepath = r'C: \ Users \ me \ BMI'' et utilisez' os.path.join (filepath, file) 'dans la méthode' read_csv'? Vous devrez peut-être aussi modifier votre code. Votre code n'est pas exactement un "exemple reproductible". J'essaie juste de vous donner des idées. – Jarad