ZIP内CSV提取指定行失败:C盘stock.csv无输出求助
解决ZIP文件中CSV提取内容后目标文件为空的问题
我太懂这种挫败感了——花了功夫写好遍历ZIP、提取特定股票数据的代码,结果C盘的stock.csv居然是空的!别慌,咱们一步步排查问题,把这个坑填上。
一、先从核心逻辑的常见坑入手
1. ZIP文件读取路径或文件匹配出错
你遍历日期对应的ZIP时,很可能路径拼接错了,或者ZIP里的CSV文件名和你预期的不一样,导致根本没读到任何数据。比如有些ZIP里的CSV可能藏在子文件夹里,或者文件名带日期后缀。
快速排查+修复代码:
import zipfile from pathlib import Path # 替换成你的日期循环变量 date_str = "20240520" zip_path = Path(f"C:/你的ZIP文件存放路径/{date_str}.zip") # 先确认ZIP文件存在 if not zip_path.exists(): print(f"⚠️ 警告:找不到ZIP文件 - {zip_path}") else: with zipfile.ZipFile(zip_path, 'r') as zf: # 找出ZIP里所有CSV文件(包括子文件夹里的) csv_files = [f for f in zf.namelist() if f.lower().endswith('.csv')] print(f"📂 当前ZIP内找到的CSV文件:{csv_files}") if not csv_files: print(f"⚠️ 警告:{zip_path} 里没有CSV文件")
2. CSV筛选逻辑的细节错误
你提到用「设置索引的方式」提取SYMBOL为HINDUNILVR的行,这里很容易踩几个小坑:
- 列名大小写不匹配:比如CSV里实际是小写的
symbol,你却用大写的SYMBOL查找 - 单元格有多余空格:比如
" HINDUNILVR "带前后空格,直接匹配会失败 - 索引设置后筛选逻辑错误:比如没确认索引是否真的包含目标值
更稳妥的筛选写法:
import pandas as pd # 接上面的ZIP读取代码 for csv_file in csv_files: with zf.open(csv_file) as f: df = pd.read_csv(f) # 先打印列名,确认是不是你要的字段 print(f"📋 当前CSV的列名:{df.columns.tolist()}") # 统一列名为大写,避免大小写问题 df.columns = df.columns.str.upper() if 'SYMBOL' not in df.columns: print(f"⚠️ 警告:{csv_file} 里没有SYMBOL列") continue # 筛选时去掉单元格前后空格,同时统一大写匹配 selected_rows = df[df['SYMBOL'].str.strip().upper() == 'HINDUNILVR'] print(f"🔍 找到符合条件的行数:{len(selected_rows)}")
3. 写入CSV的方式错误
如果每次循环都用mode='w'覆盖文件,那最后一次循环如果没找到数据,就会把之前的内容清空;另外,第一次写入后后续循环还写表头也会导致数据混乱。
正确的追加写入写法:
import pandas as pd import zipfile from pathlib import Path target_csv = Path("C:/stock.csv") # 第一次写入时才写表头,后续追加不写 write_header = not target_csv.exists() # 你的日期循环 for date_str in ["20240520", "20240521"]: zip_path = Path(f"C:/你的ZIP路径/{date_str}.zip") if not zip_path.exists(): continue with zipfile.ZipFile(zip_path, 'r') as zf: csv_files = [f for f in zf.namelist() if f.lower().endswith('.csv')] for csv_file in csv_files: with zf.open(csv_file) as f: df = pd.read_csv(f) df.columns = df.columns.str.upper() if 'SYMBOL' not in df.columns: continue selected_rows = df[df['SYMBOL'].str.strip().upper() == 'HINDUNILVR'] if len(selected_rows) == 0: print(f"❌ {date_str} 的ZIP里没找到HINDUNILVR数据") continue # 追加写入,控制表头 selected_rows.to_csv(target_csv, mode='a', header=write_header, index=False) # 第一次写入后,后续不再写表头 write_header = False
二、额外的调试小技巧
- 每一步加打印:打印当前处理的ZIP文件名、CSV文件名、筛选到的行数,快速定位哪一步没拿到数据
- 单独测试单个ZIP:先拿一个确定有
HINDUNILVR数据的ZIP,单独写一段代码测试读取和筛选,确认逻辑没问题再套循环 - 检查编码问题:有些CSV用了非UTF-8编码(比如GBK),读取时要加
encoding='gbk',否则会读错数据甚至报错
内容的提问来源于stack exchange,提问作者MUKUNDHAN JAYARAMAN
相关产品推荐
相关产品推荐

