Pandas:使用循环和分层索引将多个 csv 文件导入数据帧

Posted

技术标签:

【中文标题】Pandas:使用循环和分层索引将多个 csv 文件导入数据帧【英文标题】:Pandas: import multiple csv files into dataframe using a loop and hierarchical indexing 【发布时间】:2014-02-04 15:50:00 【问题描述】:

我想将目标目录中的多个 CSV 文件(具有不同列数)读取到单个 Python Pandas DataFrame 中,以有效地搜索和提取数据。

示例文件:

Events 
1,0.32,0.20,0.67
2,0.94,0.19,0.14,0.21,0.94
3,0.32,0.20,0.64,0.32
4,0.87,0.13,0.61,0.54,0.25,0.43 
5,0.62,0.21,0.77,0.44,0.16

这是我目前所拥有的:

# get a list of all csv files in target directory
my_dir = "C:\\Data\\"
filelist = []
os.chdir( my_dir )
for files in glob.glob( "*.csv" ) :
    filelist.append(files)

# read each csv file into single dataframe and add a filename reference column 
# (i.e. file1, file2, file 3) for each file read
df = pd.DataFrame()
columns = range(1,100)
for c, f in enumerate(filelist) :
    key = "file%i" % c
    frame = pd.read_csv( (my_dir + f), skiprows = 1, index_col=0, names=columns )
    frame['key'] = key
    df = df.append(frame,ignore_index=True)

(索引无法正常工作)

基本上,下面的脚本正是我想要的(经过试验和测试),但需要循环遍历 10 个或更多 csv 文件:

df1 = pd.DataFrame()
df2 = pd.DataFrame()
columns = range(1,100)
df1 = pd.read_csv("C:\\Data\\Currambene_001y09h00m_events.csv", 
                  skiprows = 1, index_col=0, names=columns)
df2 = pd.read_csv("C:\\Data\\Currambene_001y12h00m_events.csv", 
                  skiprows = 1, index_col=0, names=columns)
keys = [('file1'), ('file2')]
df = pd.concat([df1, df2], keys=keys, names=['fileno'])

我找到了许多相关链接,但是我仍然无法使其正常工作:

Reading Multiple CSV Files into Python Pandas Dataframe Merge of multiple data frames of different number of columns into one big data frame Import multiple csv files into pandas and concatenate into one DataFrame

【问题讨论】:

pandas.concat 将允许您使用包含 DataFrame 的任意长度的列表。使用包含所有文件的单个列表提供第一个参数,您将不必再循环脚本。 【参考方案1】:

您需要决定要在哪个轴上附加文件。 Pandas 将始终尝试通过以下方式做正确的事情:

    假设每个文件中的每一列都不同,必要时将数字附加到文件中名称相似的列中,以免混淆; 文件中属于同一行索引的项目并排放置在各自的列下。

高效追加的诀窍是将文件倾斜,这样您就可以获得与pandas.concat 将要执行的操作相匹配的所需行为。这是我的食谱:

from pandas import *
files = !ls *.csv # IPython magic
d = concat([read_csv(f, index_col=0, header=None, axis=1) for f in files], keys=files)

注意read_csvaxis=1 转置,因此它将在列轴上连接,保留其名称。如果需要,可以使用d.T 将生成的 DataFrame 转回。

编辑:

对于每个源文件中不同的列数,您需要提供一个标题。我知道您的源文件中没有标题,所以让我们用一个简单的函数创建一个:

def reader(f):
    d = read_csv(f, index_col=0, header=None, axis=1)
    d.columns = range(d.shape[1])
    return d

df = concat([reader(f) for f in files], keys=files)

【讨论】:

当每一行都有相同的列数时,效果很好。对不同的列长度有什么建议??? d = pd.concat([(read_csv((TP_dir + f), index_col=0, header=0).T) for f in filelist], keys=filelist) 这是一个不错的 ipython 技巧! ...你不能使用axis = 1来连接以避免.T吗? @mellover,给它一个标题。来自文件或范围,就像您在脚本中所做的那样。 @AndyHayden,是的!当我用concat 尝试axis = 1 并失败时,我一定是在使用pandas 0.12 或做其他错误。不是它有效。 :) 调整后完美运行。谢谢

以上是关于Pandas:使用循环和分层索引将多个 csv 文件导入数据帧的主要内容,如果未能解决你的问题,请参考以下文章

在 pandas 中,set_index 不创建分层索引

如何使用分层索引保存和检索 Pandas 数据帧?

如何在 Python 中使用 Pandas 数据结构附加多个 CSV 文件

使用自定义名称将多个pandas DataFrame输出为CSV

Python pandas数据框“日期”索引xlsx和csv中的不同格式

如何使用 pandas.read_csv() 将索引数据读取为字符串?