首页 > 解决方案 > 将许多 txt/csv 文件编译为单个数据框,并将文件名添加为列

问题描述

我正在努力编译许多文件并同时将文件名作为列添加到结果数据框中。以下脚本有效,但不知何故只对单个文件执行操作......为什么不将所有文件拉在一起?

import glob
import pandas as pd
import os

#  format Working but only reads 1 file

indir = "C:\\location\test"
outfile = "C:\\location\test\output.csv"
#  Change the directory to where the files are located
os.chdir(indir)

#  Make an empty list
filelist = []

#  Populate list with filenames.  structure criteria with wild cards
for files in glob.glob('*.txt'):
    filelist.append(files)

print(filelist)  # so far so good, all files are in the list

#  apply a for loop to the files listed above by glob
for files in filelist:
 # built up dataframes and append the filepath as a column
    frame = [pd.read_csv(files, skiprows=21, header=None, 
delim_whitespace=True).assign(Filename=os.path.basename(files))]
    df = pd.concat(frame, ignore_index=True)
    df.columns = ['Wavelength', 'Value', 'Filename']
    df.to_csv(outfile, index=None)
    print(df)

我知道已经有一些线程在处理类似的问题,但是这些线程以某种方式让我来到了这堵特殊的砖墙上。

顺便说一句,源文件的形状是 2256 行,两列(波长和值),我现在用 assign(Filename=os.path.basename()) 添加 Filename 列。

标签: pythonlistpandascsvglob

解决方案


您正在将for循环与列表理解结合/混淆。选择一个或另一个,而不是两者,进行迭代filelist。此外,您的连接应该出现在for循环或列表理解之外。

例如,在这里,您可以使用列表推导,然后提供给pd.concat

filelist = list(glob.glob('*.txt'))

frames = [pd.read_csv(fp, skiprows=21, header=None, delim_whitespace=True)\
            .assign(Filename=os.path.basename(fp)) for fp in filelist]

df = pd.concat(frames, ignore_index=True)
df.columns = ['Wavelength', 'Value', 'Filename']
df.to_csv(outfile, index=None)

推荐阅读