Snakemake技术问询:如何读取CSV列表并批量下载S3遥感数据
解决Snakemake中读取动态生成CSV并批量下载的问题
首先修正你代码里的两处明显错误:
rull拼写应为ruleexpand语法错误,正确格式应为expand('模板', 变量=列表)
接下来针对读取CSV内容作为动态输出列表的需求,核心思路是利用Snakemake的动态输出函数——因为CSV是query规则生成的产物,初始化工作流时文件还不存在,无法用全局变量提前读取,必须在规则执行阶段动态获取内容。
步骤1:编写读取CSV的辅助函数
在Snakemake脚本开头添加Python函数,负责读取指定CSV并返回目标文件路径列表:
import pandas as pd def get_target_datasets(wildcards): # 读取query规则生成的CSV,假设CSV第一列是要下载的数据集文件名(可根据实际列名调整) csv_path = f"results/{wildcards.file}.csv" df = pd.read_csv(csv_path) # 返回每个数据集对应的本地存储路径 return [f"data/{ds}" for ds in df.iloc[:, 0].tolist()]
如果你的CSV没有表头,记得加上header=None参数;如果列名不是第一列,把df.iloc[:, 0]换成对应的列名(比如df['dataset_name'])。
步骤2:修改download规则
利用上述函数定义动态输出,并调整shell命令实现批量下载:
rule download: input: csv_list = "results/{file}.csv" output: get_target_datasets # 动态生成输出路径列表 shell: """ # 跳过CSV表头(如果有表头的话),逐行读取数据集名称并执行下载 awk 'NR>1 {{print $1}}' {input.csv_list} | while read -r ds_name; do aws s3 cp "s3://eodata/Sentinel-2/MSI/L2A/2024/01/15/$ds_name" "data/$ds_name" done """
这里用awk跳过表头(如果CSV没有表头,去掉NR>1),然后循环执行aws s3 cp命令,把S3上的文件下载到本地data目录。
步骤3:更新all规则
让all规则依赖最终的下载文件,确保工作流能完整执行:
localrules: all rule all: input: get_target_datasets(file="test") # 对应你测试用的test.csv rule query: input: "input/{file}.csv" output: "results/{file}.csv" shell: "python search_catalog.py {input} {output}"
关键说明
- 不能用全局
DATASET变量:因为Snakemake初始化时,query规则还没执行,results/test.csv不存在,全局变量无法读取内容。 - 动态输出函数会在
query规则执行完成后触发,此时CSV已生成,能正确读取到待下载列表。
内容的提问来源于stack exchange,提问作者Nikko
相关产品推荐
相关产品推荐

