Python遍历CSV生成DataFrame批量执行相同操作:循环缩进与可泛化代码咨询
问题核心:缩进层级错位导致代码未按预期执行
你遇到的问题完全是Python代码块的缩进规则导致的:你目前写的df.set_index()、lista.append(df)这两行统一处理代码,位于外层年份循环内部、if/else下属的文件遍历循环之外,直接会引发两个问题:
- 每个年份目录下如果匹配到多个CSV文件,内层的文件循环会反复覆盖
df变量,最终只会处理该年份下最后一个CSV对应的DataFrame,前面所有读取的文件对应的df都会被丢弃 - 如果某个年份目录下没有匹配到任何CSV文件,
df变量根本没有被定义,后续执行处理代码时会直接抛出NameError
正确实现逻辑
我们要达到的效果是:每读完一个CSV文件生成一个新的DataFrame,立刻对它执行统一处理,处理完成后再存入目标列表。对应的代码必须放在「遍历glob匹配文件的最内层循环」的代码块里,缩进要和df = pd.read_csv(file)保持一致。
基础修正版代码
import glob import pandas as pd lista = [] for x in [2010, 2017, 2020]: # 根据年份判断文件所在的子目录 if x > 2015: file_pattern = f'My Documents\Analysis\{x}\LateAnalysis\\*.csv' else: file_pattern = f'My Documents\Analysis\{x}\Early_Analysis\\*.csv' # 遍历该目录下所有匹配到的CSV文件 for file in glob.glob(file_pattern): # 读取CSV生成DataFrame df = pd.read_csv(file) # ------------ 所有针对单个DataFrame的统一处理代码,都放在这一层级 ------------ df = df.set_index('date') # 如果还有其他统一操作,比如过滤空值、计算衍生列,也全部写在这里 # df = df[df['fruit'].notna()] # df['year'] = df.index.year # ------------------------------------------------------------------------- # 把处理完成的DataFrame加入列表 lista.append(df)
可泛化复用优化(推荐)
如果后续需要调整统一处理的逻辑,每次都要进循环里改代码很麻烦,可以把所有统一处理的逻辑抽成独立的函数,实现业务逻辑和文件遍历逻辑解耦:
# 单独定义统一处理函数,所有读取到的DataFrame都会走这个逻辑 def process_single_df(df): # 在这里写所有固定要执行的操作,需要调整逻辑只改这个函数即可 df = df.set_index('date') # 示例其他可复用操作: # df = df.dropna(subset=['fruit']) # df['value'] = df['price'] * df['count'] return df # 主循环部分 lista = [] for x in [2010, 2017, 2020]: if x > 2015: file_pattern = f'My Documents\Analysis\{x}\LateAnalysis\\*.csv' else: file_pattern = f'My Documents\Analysis\{x}\Early_Analysis\\*.csv' for file in glob.glob(file_pattern): df = pd.read_csv(file) # 直接调用处理函数,不用在循环里写重复逻辑 processed_df = process_single_df(df) lista.append(processed_df)
这种写法的优势是:后续不管是要批量新增处理步骤、还是修改现有逻辑,都只需要改动process_single_df函数,不需要碰外层的文件遍历逻辑,复用性非常高。
内容的提问来源于stack exchange,提问作者asd
相关产品推荐
相关产品推荐

