如何递归合并多层嵌套子文件夹CSV并生成pandas DataFrame
三层嵌套目录CSV合并方案
原有代码问题点
- 初版glob写法未开启递归匹配,默认仅搜索指定路径下的直接文件,无法命中多层子文件夹内的CSV,且路径拼接缺少层级通配符
- 第二版os.walk写法存在两处错误:
- 路径使用占位符未替换为实际地址,且
~开头的路径不会被os模块自动解析为用户主目录,会导致遍历不到目标文件 dfs是存储多个DataFrame的列表对象,不存在.head()方法,必须先将所有子表合并为单个DataFrame后才能调用pandas的DataFrame方法
- 路径使用占位符未替换为实际地址,且
可直接运行的实现方案
方案1:pandas glob递归匹配(代码最简洁)
不需要手动写多层循环,直接通过glob的递归参数匹配所有层级的CSV文件:
import pandas as pd import glob import os # 替换为你的实际存储根目录,os.path.expanduser会自动解析~代表的用户主目录 root_path = os.path.expanduser("~/root/up/to/the/folder/") # 递归匹配根目录下任意层级子文件夹中的所有csv文件 all_csv_path = glob.glob(os.path.join(root_path, "**", "*.csv"), recursive=True) # 读取所有文件并合并为单个DataFrame,ignore_index=True重置连续索引避免重复 combined_df = pd.concat([pd.read_csv(f) for f in all_csv_path], ignore_index=True) # 合并完成后可正常调用head预览前5行 print(combined_df.head())
可选优化:如果需要追溯数据来源,可以在读取时给每个子表加上文件路径/从路径提取年、月、日字段,避免不同日期数据混在一起后无法区分。
方案2:os.walk遍历实现(兼容原有写法)
修复原有os.walk版本的问题,增加异常捕获和可选的日期字段提取逻辑:
import os import pandas as pd root_path = os.path.expanduser("<替换为你的实际根目录路径>") csv_suffix = ".csv" csv_path_list = [] # 遍历所有子目录收集csv文件路径 for root, dirs, files in os.walk(root_path): for file in files: # 转小写判断后缀,兼容.CSV等大写后缀的异常情况 if file.lower().endswith(csv_suffix): csv_path_list.append(os.path.join(root, file)) df_list = [] for path in csv_path_list: try: temp_df = pd.read_csv(path) # 可选:从三层嵌套路径中提取年、月、日作为新列,路径结构为 根目录/年/月/日/文件.csv path_split = path.split(os.sep) temp_df["year"] = path_split[-4] temp_df["month"] = path_split[-3] temp_df["day"] = path_split[-2] df_list.append(temp_df) except Exception as e: print(f"读取文件{path}出错:{str(e)}") combined_df = pd.concat(df_list, ignore_index=True) print(combined_df.head())
方案3:终端/PowerShell 无代码快速合并
不需要运行Python脚本,直接通过系统命令合并所有CSV为单个文件:
- Windows PowerShell 执行:
# 进入CSV根目录后执行,递归读取所有csv并导出为根目录下的combined.csv Get-ChildItem -Recurse -Filter *.csv | ForEach-Object { Import-Csv $_.FullName } | Export-Csv -Path .\combined.csv -NoTypeInformation -Encoding UTF8
- Linux/macOS 终端执行:
# 先提取第一个CSV的表头写入目标文件,再追加所有CSV的内容(跳过每个文件的表头行) find . -name "*.csv" | head -1 | xargs head -n 1 > combined.csv find . -name "*.csv" -exec tail -n +2 {} \; >> combined.csv
内容的提问来源于stack exchange,提问作者doubleD
相关产品推荐
相关产品推荐

