如何基于UCC多条件筛选同一列数据并关联NEWID合并多表?
问题描述
我需要分析其他因素对UCC=180620的COST的影响。UCC=290420、320130、410901与180620同属expd表的UCC列,同一NEWID可对应多个不同UCC。具体需求:
- 先筛选出关联过UCC=180620的所有NEWID;
- 获取这些NEWID对应的UCC=180620、290420、320130、410901的COST数据;
- 将expd表与fmld、fmli、memd表通过NEWID进行左关联;
- 最终将各年份数据合并到单个total.csv文件中。
原代码存在筛选逻辑错误、语法错误和缩进问题,以下是修正后的完整实现:
修正后的代码
import os import pandas as pd def concat_df(file_list): df = pd.DataFrame() for f in file_list: tmp_df = pd.read_csv(f) df = pd.concat((df, tmp_df), axis=0) return df root_dir = 'ce survey' if os.path.exists('total.csv'): os.remove('total.csv') years = list(range(2012, 2022)) for year in years: print(year) dir_path = os.path.join(root_dir, str(year)) files = os.listdir(dir_path) expd_files = [] fmld_files = [] fmli_files = [] memd_files = [] for file in files: if file.endswith('.csv'): fp = os.path.join(dir_path, file) if 'expd' in file: expd_files.append(fp) elif 'fmld' in file: fmld_files.append(fp) elif 'fmli' in file: fmli_files.append(fp) elif 'memd' in file: memd_files.append(fp) # 修复:将memd文件添加到正确列表 expd_df = concat_df(expd_files) fmld_df = concat_df(fmld_files) fmli_df = concat_df(fmli_files) memd_df = concat_df(memd_files) # 步骤1:筛选关联过UCC=180620的所有NEWID target_newids = expd_df[expd_df['UCC'] == 180620]['NEWID'].unique() # 步骤2:获取这些NEWID对应的目标UCC数据 target_uccs = [180620, 290420, 320130, 410901] expd_df = expd_df[(expd_df['NEWID'].isin(target_newids)) & (expd_df['UCC'].isin(target_uccs))][['NEWID', 'COST', 'UCC', 'EXPNYR']] # 处理fmld表字段 if year in [2015, 2016, 2017]: fmld_df = fmld_df[['NEWID', 'REGION', 'FWAGEX', 'INC_RANK', 'HISP_REF', 'HORREF1', 'HORREF2', 'RACE2', 'REF_RACE', 'EDUC_REF', 'FAM_SIZE', 'INCLASS','FAM_TYPE','CHILDAGE']] elif year in [2018, 2019, 2020, 2021]: fmld_df = fmld_df[['NEWID', 'REGION', 'FWAGEX', 'INC_RANK', 'HISP_REF', 'HORREF1', 'HORREF2', 'RACE2', 'REF_RACE', 'EDUC_REF', 'FAM_SIZE','FAM_TYPE','CHILDAGE']] else: fmld_df = fmld_df[['NEWID', 'REGION', 'FWAGEX', 'INC_RANK', 'HISP_REF', 'HORREF1', 'HORREF2', 'RACE2', 'REF_RACE', 'EDUC_REF', 'FAM_SIZE', 'FINCAFTX', 'INCLASS']] # 处理fmli表字段 if year == 2012: fmli_df = fmli_df[['NEWID', 'INCLASS2', 'RACE2']] else: fmli_df = fmli_df[['NEWID', 'INCLASS2', 'RACE2', 'FINATXEM']] # 处理memd表字段 memd_df = memd_df[['NEWID','CU_CODE1','EMPLTYPE', 'SEX', 'OCCUEARN', 'OCCULIST', 'AGE', 'WKS_WRKD', 'MARITAL']] # 步骤3:左关联各表 expd_df = pd.merge(left=expd_df, right=fmld_df, on='NEWID', how='left') expd_df = pd.merge(left=expd_df, right=fmli_df, on='NEWID', how='left') expd_df = pd.merge(left=expd_df, right=memd_df, on='NEWID', how='left') # 补充缺失字段 if year == 2012: expd_df['FINATXEM'] = '' if year in [2015, 2016, 2017]: expd_df['FINCAFTX'] = '' elif year in [2018, 2019, 2020, 2021]: expd_df['INCLASS'] = '' expd_df['FINCAFTX'] = '' expd_df['YEAR'] = year # 整理输出字段(保留原需求的字段,同时新增YEAR) output_cols = ['NEWID', 'COST', 'UCC', 'EXPNYR', 'YEAR', 'REGION', 'FWAGEX', 'INC_RANK', 'HISP_REF', 'HORREF1', 'HORREF2', 'RACE2_x', 'REF_RACE', 'EDUC_REF', 'FAM_SIZE', 'FINCAFTX', 'INCLASS', 'INCLASS2', 'RACE2_y', 'FINATXEM', 'CU_CODE1','EMPLTYPE', 'SEX', 'OCCUEARN', 'OCCULIST', 'AGE', 'WKS_WRKD', 'MARITAL'] expd_df = expd_df[output_cols] # 写入total.csv if year == 2012: expd_df.to_csv('total.csv', mode='a', index=False) else: expd_df.to_csv('total.csv', mode='a', index=False, header=None)
关键修正点
- 修复筛选逻辑:先提取所有关联过UCC=180620的NEWID,再筛选这些NEWID对应的4个目标UCC数据,完全符合需求;
- 修复文件收集错误:将memd文件正确添加到memd_files列表;
- 修正语法与缩进:修复concat_df函数和变量的缩进问题,删除原代码中语法错误的字段选择逻辑;
- 优化字段处理:用列表in操作简化年份判断,整理输出字段确保包含所有关联表的必要信息;
- 补充缺失字段:确保不同年份的输出字段统一,避免合并时出现列不匹配问题。
内容的提问来源于stack exchange,提问作者Se Youuu
相关产品推荐
相关产品推荐

