Import multiple csv files into pandas and concatenate into one DataFrame
我想从目录中读取几个csv文件到pandas并将它们连接成一个大的DataFrame。 我虽然无法弄明白。 这是我到目前为止:
1 2 3 4 5 6 7 8 9 10 11 12 13 | 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) |
我想在for循环中需要一些帮助???
如果所有
我添加了
1 2 3 4 5 6 7 8 9 10 11 12 13 | import pandas as pd import glob path = r'C:\DRO\DCL_rawdata_files' # use your path all_files = glob.glob(path +"/*.csv") li = [] for filename in all_files: df = pd.read_csv(filename, index_col=None, header=0) li.append(df) frame = pd.concat(li, axis=0, ignore_index=True) |
替代darindaCoder的答案:
1 2 3 4 5 6 | 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 |
1 2 | import glob, os df = pd.concat(map(pd.read_csv, glob.glob(os.path.join('',"my_files*.csv")))) |
Dask库可以从多个文件中读取数据帧:
1 2 | >>> import dask.dataframe as dd >>> df = dd.read_csv('data*.csv') |
(来源:http://dask.pydata.org/en/latest/examples/dataframe-csv.html)
Dask数据帧实现了Pandas数据帧API的子集。如果所有数据都适合内存,则可以调用
这里几乎所有的答案都是不必要的复杂(全局模式匹配)或依赖其他第三方库。您可以使用Pandas和python(所有版本)已经内置的所有内容在2行中执行此操作。
对于一些文件 - 1个班轮:
1 | df = pd.concat(map(pd.read_csv, ['data/d1.csv', 'data/d2.csv','data/d3.csv'])) |
对于许多文件:
1 2 3 4 | from os import listdir filepaths = [f for f in listdir("./data") if f.endswith('.csv')] df = pd.concat(map(pd.read_csv, filepaths)) |
这个设置df的pandas线使用了3个东西:
在文件路径中)。
编辑:我用谷歌搜索到https://stackoverflow.com/a/21232849/186078。
然而,最近我发现使用numpy进行任何操作然后将其分配给数据帧而不是在迭代的基础上操纵数据帧本身更快,它似乎也适用于此解决方案。
我真诚地希望任何人都能在这个页面上考虑这种方法,但是不要将这段巨大的代码作为评论附加在一起并使其不那么易读。
您可以利用numpy来加速数据帧连接。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 | 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"....] |
时间统计:
1 2 3 4 5 | 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 --- |
如果要以递归方式搜索(Python 3.5或更高版本),可以执行以下操作:
1 2 3 4 5 6 7 8 | 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) |
请注意,最后三行可以用一行表示:
1 | df = pd.concat((pd.read_csv(f) for f in iglob(path, recursive=True)), ignore_index=True) |
您可以在此处找到
编辑:多平台递归函数:
您可以将上述内容包装到多平台功能(Linux,Windows,Mac)中,这样您就可以:
1 | df = read_df_rec('C:\user\your\path', *.csv) |
这是功能:
1 2 3 4 5 6 7 | 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来读取所有文件并连接如下:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 | 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))) |
使用
1 2 3 4 5 6 | import pandas as pd import glob import functools df = pd.concat(map(functools.partial(pd.read_csv, sep='|', compressed=None), glob.glob("data/*.csv"))) |
注意:
我觉得这个方法很优雅。
1 2 3 4 5 6 7 8 9 | import pandas as pd import os big_frame = pd.DataFrame() for file in os.listdir(): if file.endswith('.csv'): df = pd.read_csv(file) big_frame = big_frame.append(df, ignore_index=True) |
另一个带有列表理解的内联,允许使用read_csv参数。
1 | df = pd.concat([pd.read_csv(f'dir/{f}') for f in os.listdir('dir') if f.endswith('.csv')]) |
简单快捷
导入2个或更多
1 2 3 | import glob df = pd.concat(map(pd.read_csv, glob.glob('data/*.csv')) |