我想从目录中读取几个CSV文件到熊猫,并将它们连接到一个大的DataFrame。不过我还没弄明白。以下是我目前所掌握的:
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循环中需要一些帮助?
如果你想递归搜索(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)
这里几乎所有的答案要么是不必要的复杂(glob模式匹配),要么依赖于额外的第三方库。您可以在两行中使用Pandas和Python(所有版本)已经内置的所有内容来完成此操作。
对于一些文件-一行程序
df = pd.concat(map(pd.read_csv, ['d1.csv', 'd2.csv','d3.csv']))
对于许多文件
import os
filepaths = [f for f in os.listdir(".") if f.endswith('.csv')]
df = pd.concat(map(pd.read_csv, filepaths))
对于无头文件
如果你想用pd改变一些特定的东西。Read_csv(即,没有头),你可以创建一个单独的函数,并调用你的地图:
def f(i):
return pd.read_csv(i, header=None)
df = pd.concat(map(f, filepaths))
这条pandas行,它设置了df,利用了三个东西:
Python的map (function, iterable)发送给函数(the
pd.read_csv())迭代对象(我们的列表),它是每个CSV元素
在filepaths)。
Panda的read_csv()函数正常读取每个CSV文件。
Panda的concat()将所有这些都放在一个df变量下。
基于希德的好答案。
识别列缺失或未对齐的问题
在连接之前,您可以将CSV文件加载到一个中间字典中,该字典根据文件名(以dict_of_df['filename.csv']的形式)访问每个数据集。这样的字典可以帮助您识别异构数据格式的问题,例如当列名没有对齐时。
导入模块并定位文件路径:
import os
import glob
import pandas
from collections import OrderedDict
path =r'C:\DRO\DCL_rawdata_files'
filenames = glob.glob(path + "/*.csv")
注意:OrderedDict不是必需的,但它将保持文件的顺序,这可能对分析有用。
加载CSV文件到字典中。然后连接:
dict_of_df = OrderedDict((f, pandas.read_csv(f)) for f in filenames)
pandas.concat(dict_of_df, sort=True)
键为文件名称f,值为CSV文件的数据帧内容。
除了使用f作为字典键,你还可以使用os.path.basename(f)或其他os.path.basename(f)。方法将字典中键的大小减少到仅相关的较小部分。
考虑使用convtools库,它提供了大量数据处理原语,并在底层生成简单的临时代码。
它不应该比熊猫/极地快,但有时它可以。
例如,你可以连接到一个CSV文件进一步重用-这是代码:
import glob
from convtools import conversion as c
from convtools.contrib.tables import Table
import pandas as pd
def test_pandas():
df = pd.concat(
(
pd.read_csv(filename, index_col=None, header=0)
for filename in glob.glob("tmp/*.csv")
),
axis=0,
ignore_index=True,
)
df.to_csv("out.csv", index=False)
# took 20.9 s
def test_convtools():
table = None
for filename in glob.glob("tmp/*.csv"):
table_ = Table.from_csv(filename, header=False)
if table is None:
table = table_
else:
table = table.chain(table_)
table.into_csv("out_convtools.csv", include_header=False)
# took 15.8 s
当然,如果你只是想获得一个数据帧而不写入一个连接文件,它将相应地花费4.63秒和10.9秒(pandas在这里更快,因为它不需要压缩列来写入回)。