使用Pandas递归处理子目录CSV并合并的技术求助
解决递归处理发票CSV并合并的问题
咱们先梳理下你原代码里的几个核心问题,这也是它没法正常工作的原因:
os.listdir()只能扫描当前目录,没法递归钻进子文件夹,自然处理不了Invoice1folder这类子目录里的CSV文件endswith('*_Invoice.csv')用法错误,endswith不支持通配符*,要匹配结尾是_Invoice.csv的文件,直接写endswith('_Invoice.csv')就行file.name会报错,因为file只是字符串类型的文件名,不是文件对象,没法调用.name属性DataFrame.append()已经被Pandas弃用,官方现在推荐用pd.concat()来合并数据- 循环逻辑混乱,同一个循环里同时处理原文件和生成的精简文件,很容易出现重复处理或漏处理的情况
下面是修正后的完整代码,完全匹配你的需求:
import pandas as pd import os import fnmatch # 用于文件名匹配,也可以直接用字符串判断替代 # 定义配置项 columns_to_keep = ['A', 'C'] root_directory = '/Invoice List/' # -------------------------- # 第一步:递归处理所有_Invoice.csv,生成精简版文件 # -------------------------- for current_root, subdirs, files in os.walk(root_directory): for file in files: # 匹配每个子目录中的目标文件 if fnmatch.fnmatch(file, '_Invoice.csv'): # 构建完整文件路径,避免路径分隔符问题 full_file_path = os.path.join(current_root, file) # 读取CSV并保留指定列 raw_df = pd.read_csv(full_file_path) reduced_df = raw_df.loc[:, columns_to_keep] # 构建精简版文件的保存路径 reduced_file_path = os.path.join(current_root, '_Invoice_Reduced.csv') # 保存精简版CSV,index=False避免写入多余索引列 reduced_df.to_csv(reduced_file_path, index=False) # -------------------------- # 第二步:合并所有_Invoice_Reduced.csv到一个DataFrame # -------------------------- merged_data = pd.DataFrame() reduced_file_list = [] # 再次递归遍历,收集所有精简版文件路径 for current_root, subdirs, files in os.walk(root_directory): for file in files: if fnmatch.fnmatch(file, '_Invoice_Reduced.csv'): reduced_file_list.append(os.path.join(current_root, file)) # 一次性合并所有文件,比循环append更高效 if reduced_file_list: merged_data = pd.concat([pd.read_csv(file) for file in reduced_file_list], ignore_index=True) # 按需保存合并后的结果,例如: # merged_data.to_csv('/Invoice List/All_Merged_Invoices.csv', index=False)
代码关键点说明:
os.walk(root_directory):会递归遍历指定根目录下的所有子目录,返回当前目录路径、子目录列表、文件列表,完美解决递归遍历需求os.path.join():自动适配不同操作系统的路径分隔符,避免手动拼接路径出现错误pd.concat():官方推荐的DataFrame合并方式,比append效率更高,ignore_index=True会重置合并后的索引,避免索引混乱index=False:保存CSV时添加该参数,不会将Pandas的索引列写入文件,避免产生多余的无意义列
内容的提问来源于stack exchange,提问作者Dante Smith
相关产品推荐
相关产品推荐

