para - leer archivos csv en python
Importe mĂșltiples archivos csv a pandas y concatene en un DataFrame (8)
Me gustaría leer varios archivos csv de un directorio a pandas y concatenarlos en un gran DataFrame. Aunque no he podido averiguarlo. Aquí está lo que tengo hasta ahora:
import glob
import pandas as pd
# get data file names
path =r''C:/DRO/DCL_rawdata_files''
filenames = glob.glob(path + "/*.csv")
dfs = []
for filename in filenames:
dfs.append(pd.read_csv(filename))
# Concatenate all data into one DataFrame
big_frame = pd.concat(dfs, ignore_index=True)
Supongo que necesito algo de ayuda dentro del bucle for?
Edición: Busqué en Google en https://.com/a/21232849/186078 . Sin embargo, últimamente encuentro que es más rápido realizar cualquier manipulación utilizando numpy y luego asignarlo una vez al marco de datos en lugar de manipular el propio marco de datos en forma iterativa y parece funcionar también en esta solución.
Sinceramente, quiero que cualquier persona que visite esta página considere este enfoque, pero no quiero adjuntar esta enorme pieza de código como comentario y hacerlo menos legible.
Puede aprovechar numpy para acelerar realmente la concatenación del marco de datos.
import os
import glob
import pandas as pd
import numpy as np
path = "my_dir_full_path"
allFiles = glob.glob(os.path.join(path,"*.csv"))
np_array_list = []
for file_ in allFiles:
df = pd.read_csv(file_,index_col=None, header=0)
np_array_list.append(df.as_matrix())
comb_np_array = np.vstack(np_array_list)
big_frame = pd.DataFrame(comb_np_array)
big_frame.columns = ["col1","col2"....]
Estadísticas de tiempo:
total files :192
avg lines per file :8492
--approach 1 without numpy -- 8.248656988143921 seconds ---
total records old :1630571
--approach 2 with numpy -- 2.289292573928833 seconds ---
La biblioteca Dask puede leer un marco de datos de varios archivos:
>>> import dask.dataframe as dd
>>> df = dd.read_csv(''data*.csv'')
(Fuente: http://dask.pydata.org/en/latest/examples/dataframe-csv.html )
Los marcos de datos de Dask implementan un subconjunto de la API de marcos de datos de Pandas. Si todos los datos df.compute()
en la memoria, puede llamar a df.compute()
para convertir el marco de datos en un marco de datos de Pandas.
Si desea buscar de forma recursiva ( Python 3.5 o superior ), puede hacer lo siguiente:
from glob import iglob
import pandas as pd
path = r''C:/user/your/path/**/*.csv''
all_rec = iglob(path, recursive=True)
dataframes = (pd.read_csv(f) for f in all_rec)
big_dataframe = pd.concat(dataframes, ignore_index=True)
Tenga en cuenta que las tres últimas líneas se pueden expresar en una sola línea :
df = pd.concat((pd.read_csv(f) for f in iglob(path, recursive=True)), ignore_index=True)
Puedes encontrar la documentación de **
here . Además, utilicé iglob
lugar de glob
, ya que devuelve un iterador en lugar de una lista.
EDIT: Función recursiva multiplataforma:
Puede envolver lo anterior en una función multiplataforma (Linux, Windows, Mac), por lo que puede hacer:
df = read_df_rec(''C:/user/your/path'', *.csv)
Aquí está la función:
from glob import iglob
from os.path import join
import pandas as pd
def read_df_rec(path, fn_regex=r''*.csv''):
return pd.concat((pd.read_csv(f) for f in iglob(
join(path, ''**'', fn_regex), recursive=True)), ignore_index=True)
Si los archivos csv múltiples están comprimidos, puede usar un archivo zip para leer todos y concatenar como se muestra a continuación:
import zipfile
import numpy as np
import pandas as pd
ziptrain = zipfile.ZipFile(''yourpath/yourfile.zip'')
train=[]
for f in range(0,len(ziptrain.namelist())):
if (f == 0):
train = pd.read_csv(ziptrain.open(ziptrain.namelist()[f]))
else:
my_df = pd.read_csv(ziptrain.open(ziptrain.namelist()[f]))
train = (pd.DataFrame(np.concatenate((train,my_df),axis=0),
columns=list(my_df.columns.values)))
Si tiene las mismas columnas en todos sus archivos csv
, puede probar el siguiente código. He agregado header=0
para que después de leer la primera fila de csv
se puedan asignar como nombres de columna.
path =r''C:/DRO/DCL_rawdata_files'' # use your path
allFiles = glob.glob(path + "/*.csv")
list_ = []
for file_ in allFiles:
df = pd.read_csv(file_,index_col=None, header=0)
list_.append(df)
frame = pd.concat(list_, axis = 0, ignore_index = True)
Una alternativa a la respuesta de darindaCoder :
path = r''C:/DRO/DCL_rawdata_files'' # use your path
all_files = glob.glob(os.path.join(path, "*.csv")) # advisable to use os.path.join as this makes concatenation OS independent
df_from_each_file = (pd.read_csv(f) for f in all_files)
concatenated_df = pd.concat(df_from_each_file, ignore_index=True)
# doesn''t create a list, nor does it append to one
filepaths = [''data/d1.csv'', ''data/d2.csv'',''data/d3.csv'',''data/d4.csv'']
df = pd.concat(map(pd.read_csv, filepaths))
import glob, os
df = pd.concat(map(pd.read_csv, glob.glob(os.path.join('''', "my_files*.csv"))))