求助:Pandas新增filename列失败及行索引命名文件名问题
问题:为CSV数据新增文件名列失败,后续需为每行添加带行号的文件名
原始数据(无列名)
file1.txt -> AL; 1A; file1.txt -> BL; 2A; file1.txt -> CL; 3A;
示例文件路径
C:\Users\CL\Desktop\folder\file1.txt
初始期望输出(新增filename列)
name class filename AL 1A file1.txt BL 2A file2.txt CL 3A file3.txt
当前代码(新增列失败,导出后无filename列)
import os import pandas as pd import glob src_path = r'C:\Users\CL\Desktop\folder' #3 files total for f in glob.glob(os.path.join(src_path ,"*.txt")): filename = f #file1.txt files = [pd.read_csv(f, delimiter=';', names = ['name', 'class'], index_col = False)] files_df = pd.DataFrame(files) #convert to df to add new column files_df['filename'] = f #assign value to new column files_df = pd.concat(files_df) #concat all file data together files_df.to_csv("df.csv")
更新需求:为每行数据添加索引值
更新后期望输出
name class filename AL 1A file1_1.txt AL 1A file1_2.txt BL 2A file2_1.txt BL 2A file2_2.txt CL 3A file3_1.txt CL 3A file3_2.txt
更新后尝试的代码(存在语法错误)
import os import pandas as pd import glob i = 0 src_path = r'C:\Users\CL\Desktop\folder' #3 files total pd.concat([pd.read_csv(f, delimiter=';', names=['name', 'class'], index_col=False ).assign(filename=f) for i, f in enumerate(glob.glob(os.path.join(src_path ,"*.txt"))), i+=1] ).to_csv("df.csv")
问题排查与解决方案
初始代码问题分析
- 循环变量覆盖:每次循环都会重新创建
files_df,之前文件的数据被直接覆盖,最终只保留最后一个文件的处理结果。 - 错误的DataFrame嵌套:
files = [pd.read_csv(...)]将DataFrame包装进列表,再用pd.DataFrame(files)生成嵌套结构,导致新增列的操作未作用到每行数据上。 - concat逻辑错误:循环外的
pd.concat(files_df)仅展开最后一个文件的嵌套DataFrame,而非合并所有文件的数据。
初始需求修正代码
import os import pandas as pd import glob src_path = r'C:\Users\CL\Desktop\folder' all_dfs = [] for f in glob.glob(os.path.join(src_path, "*.txt")): # 读取文件,过滤末尾空列,仅保留前两列有效数据 df = pd.read_csv(f, delimiter=';', names=['name', 'class'], index_col=False, usecols=[0,1]) # 提取纯文件名(去除完整路径) filename = os.path.basename(f) df['filename'] = filename all_dfs.append(df) # 合并所有文件的DataFrame,重置索引 files_df = pd.concat(all_dfs, ignore_index=True) files_df.to_csv("df.csv", index=False)
更新需求(带行号的文件名)修正代码
import os import pandas as pd import glob src_path = r'C:\Users\CL\Desktop\folder' all_dfs = [] for f in glob.glob(os.path.join(src_path, "*.txt")): df = pd.read_csv(f, delimiter=';', names=['name', 'class'], index_col=False, usecols=[0,1]) # 提取文件名前缀(去除后缀和路径) base_name = os.path.splitext(os.path.basename(f))[0] # 为每行生成带行号的文件名,行号从1开始 df['filename'] = [f"{base_name}_{i+1}.txt" for i in range(len(df))] all_dfs.append(df) files_df = pd.concat(all_dfs, ignore_index=True) files_df.to_csv("df.csv", index=False)
关键说明
- 用
os.path.basename(f)提取纯文件名,避免将完整路径写入列中。 - 用列表
all_dfs存储每个文件处理后的DataFrame,最后一次性合并,防止数据丢失。 - 更新需求中通过列表推导式为每行生成带行号的文件名,确保每行对应唯一索引后缀。
- 添加
usecols=[0,1]过滤原始数据末尾的空列,保证数据整洁。
内容的提问来源于stack exchange,提问作者panzers
相关产品推荐
相关产品推荐

