Импорт нескольких файлов csv в pandas и объединение в один фрейм данных
Я хотел бы прочитать несколько csv-файлов из каталога в pandas и объединить их в один большой фрейм данных. Я не смог это выяснить. Вот что у меня есть до сих пор:
import glob
import pandas as pd
# get data file names
path =r'C:DRODCL_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)
Я думаю, мне нужна помощь в цикле for???
8 ответов:
если у вас есть одинаковые столбцы во всех ваших
csvфайлы, то вы можете попробовать код ниже. Я добавилheader=0Так, что после прочтенияcsvпервая строка может быть назначен в качестве имен столбцов.path =r'C:\DRO\DCL_rawdata_files' # use your path allFiles = glob.glob(path + "/*.csv") frame = pd.DataFrame() list_ = [] for file_ in allFiles: df = pd.read_csv(file_,index_col=None, header=0) list_.append(df) frame = pd.concat(list_)
альтернатива 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
Edit: я погуглил свой путь в https://stackoverflow.com/a/21232849/186078. Однако в последнее время я нахожу, что быстрее выполнять любые манипуляции с помощью numpy, а затем назначать его один раз в dataframe, а не манипулировать самим dataframe на итерационной основе, и, похоже, он тоже работает в этом решении.
Я искренне хочу, чтобы кто-нибудь, попав на эту страницу, рассмотрел этот подход, но не хочу прикреплять этот огромный кусок кода в качестве комментария и делать его меньше читаемый.
вы можете использовать numpy, чтобы действительно ускорить конкатенацию фреймов данных.
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"....]сроки статистика:
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 ---
библиотека Dask может считывать фрейм данных из нескольких файлов:
>>> import dask.dataframe as dd >>> df = dd.read_csv('data*.csv')(источник: http://dask.pydata.org/en/latest/examples/dataframe-csv.html)
фреймы данных Dask реализуют подмножество API фреймов данных Pandas. Если все данные помещаются в память, вы можете вызов
df.compute()для преобразования фрейма данных в фрейм данных Pandas.
если вы хотите поиск рекурсивно (Python 3.5 или выше), вы можете сделать следующее:
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)обратите внимание, что три последние строки могут быть выражены в одном один строка:
df = pd.concat((pd.read_csv(f) for f in iglob(path, recursive=True)), ignore_index=True)вы можете найти документацию
**здесь. Кроме того, я использовалiglobвместоglob, так как он возвращает итератор вместо списка.
изменить: Мультиплатформенная рекурсивная функция:
вы можете обернуть выше в мультиплатформа функция (Linux, Windows, Mac), так что вы можете сделать:
df = read_df_rec('C:\user\your\path', *.csv)вот функция:
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)
если несколько файлов csv заархивированы, вы можете использовать zipfile для чтения всех и объединения, как показано ниже:
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)))
filepaths = ['data/d1.csv', 'data/d2.csv','data/d3.csv','data/d4.csv'] df = pd.concat(map(pd.read_csv, filepaths))
Comments